赞
踩
Socket又称套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开,使得应用程序不需要了解TCP/IP的细节,就能够实现传输。
TCP协议使用的send、recv、WSASend和WSARecv,
UDP协议使用的sendto、recvfrom、WSASendTo 和WSARecvFrom。
什么是WSASend?
作用:在一个已连接的套接口上发送数据。
- #include <WinSock2.h>
- #pragma comment(lib,"Ws2_32.lib ")
1. WSAStartup 初始化Ws2_32.dll的函数
- int WSAStartup(
- __in WORD wVersionRequested,
- __out LPWSADATA lpWSAData
- );
wVersionRequested
标识了用户调用的Winsock的版本号。高字节指明辅版本编号,低字节指明主版本编号。通常使用MAKEWORD来生成一个版本号。 当前Winsock sockets的版本号为2.2,用到的dll是 Ws2_32.dll。
lpWSAData
指向WSADATA结构体的指针,lpWSAData返回了系统对Windows Sockets 的描述
Return Value
如果调用成功,WSAStartup 函数返回0。否则,将返回五种错误代码之一
2. WSACleanup 释放Ws2_32.dl的l函数
int WSACleanup(void);
返回值0表示正常退出,返回值SOCKET_ERROR表示异常。返回值是SOCKET_ERROR,可以调用 WSAGetLastError.查看错误代码。需要注意的是,在多线程环境下,WSACleanup 函数将终止所有线程的socket操作。
3. socket 创建socket的函数
- SOCKET WSAAPI socket(
- __in int af,
- __in int type,
- __in int protocol
- );
-
- af ( address family)
-
- 指明地址簇类型,常用的地址簇如下,其余地址簇在Winsock2.h中定义。
-
- AF_UNSPEC(未指明)、
-
- AF_INET(IPv4)、
-
- AF_NETBIOS(NETBIOS地址簇)、
-
- AF_INET6(IPv6)、
-
- AF_IRDA(Infrared Data Association (IrDA)地址簇)、
-
- AF_BTM(Bluetooth)。
-
- type
-
- 指明socket的类型,Windows Sockets 2常见类型如下:
-
- SOCK_STREAM(流套接字,使用TCP协议)、
-
- SOCK_DGRAM(数据报套接字,使用UDP协议)、
-
- SOCK_RAW(原始套接字)、
-
- SOCK_RDM(提供可靠的消息数据报文,reliable message datagram)、
-
- SOCK_SEQPACKET(Provides a pseudo-stream packet based on datagrams,在UDP的基础上提供了伪流数据包)。
-
- protocol
-
- 指明数据传输协议,该参数取决于af和type参数的类型。protocol参数在Winsock2.h and Wsrm.h定义。通常使用如下3中协议:
-
- IPPROTO_TCP(TCP协议,使用条件,af是AF_INET or AF_INET6、type是SOCK_STREAM )
-
- IPPROTO_UDP(UDP协议,使用条件,af是AF_INET or AF_INET6、type是SOCK_DGRAM)
-
- IPPROTO_RM(PGM(Pragmatic General Multicast,实际通用组播协议)协议,使用条件,af是AF_INET 、type是SOCK_RDM)
4. bind 服务端将socket与地址关联
5. listen 服务端网络监听
6. accept 服务端connect接收
7. connect 客户端请求服务端连接
8. send 发送数据
- // WinServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
-
- #include "pch.h"
- #include <iostream>
- #include <WinSock2.h>
-
- #pragma comment(lib, "ws2_32.lib")
-
- int main()
- {
- WORD wVersion = MAKEWORD(2, 2);
- WSADATA wsaData = { 0 };
- //WinSocket初始化
- if (WSAStartup(wVersion, &wsaData))
- {
- std::cout << "WSAStartup Error" << std::endl;
- return 1;
- }
-
- //创建socket
- SOCKET nServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (nServerSocket == INVALID_SOCKET)
- {
- std::cout << "create socket Error" << std::endl;
- WSACleanup();//释放WinSocket
- return 1;
- }
-
- sockaddr_in serverAddr = { 0 };
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_port = htons(8888); //绑定端口
- serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //绑定ip
-
- //绑定ip和端口
- if (SOCKET_ERROR == bind(nServerSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)))
- {
- std::cout << "bind Error" << std::endl;
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- return 1;
- }
-
- //监听 最大连接数为5
- if (SOCKET_ERROR == listen(nServerSocket, 5))
- {
- std::cout << "listen Error" << std::endl;
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- return 1;
- }
-
- SOCKET nClientSocket = { 0 };
- sockaddr_in clientAddr = { 0 };
- int nLen = sizeof(clientAddr);
- //接受客户端连接请求
- nClientSocket = accept(nServerSocket, (sockaddr*)&clientAddr, &nLen);
- if (INVALID_SOCKET == nClientSocket)
- {
- std::cout << "accept Error" << std::endl;
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- }
-
- char szBuffer[255] = { 0 };
- int nRet = 0;
- //接收客户端数据
- while (true)
- {
- memset(szBuffer, 0, 255);
- //接受客户端发来的数据
- nRet = recv(nClientSocket, szBuffer, 255, 0);
- if (nRet == SOCKET_ERROR)
- {
- std::cout << "recv Error" << std::endl;
- closesocket(nClientSocket);
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- return 1;
- }
- std::cout << szBuffer << std::endl;
-
- nRet = send(nClientSocket, szBuffer, 255, 0);
- if (nRet == SOCKET_ERROR)
- {
- std::cout << "send Error" << std::endl;
- closesocket(nClientSocket);
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- return 1;
- }
- }
-
- closesocket(nClientSocket);
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- return 0;
- }
-
- // WinClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
-
- #include "pch.h"
- #include <iostream>
- #include <WS2tcpip.h>
- #include <WinSock2.h>
-
- #pragma comment(lib, "ws2_32.lib")
-
- int main()
- {
- WSADATA wsaData = { 0 };
- SOCKET nClientSocket = { 0 };
- int nRet = 0;
- char szBuffer[255];
-
- //WinSocket初始化
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- std::cout << "WSAStartup failed!\n";
- return 1;
- }
-
- //创建socket
- nClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (nClientSocket == INVALID_SOCKET)
- {
- std::cout << "socket failed!\n";
- //释放
- WSACleanup();
- return 1;
- }
-
- SOCKADDR_IN addrServ = { 0 };
- addrServ.sin_family = AF_INET;
- addrServ.sin_port = htons(8888); //绑定端口
- inet_pton(AF_INET, "127.0.0.1", &addrServ.sin_addr); //服务器ip
-
- //连接服务器
- nRet = connect(nClientSocket, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
- if (nRet == SOCKET_ERROR)
- {
- std::cout << "connect failed!\n";
- closesocket(nClientSocket);
- WSACleanup();
- return 1;
- }
-
- while (true)
- {
- memset(szBuffer, 0, 255);
- std::cout << "Please input a string:";
- std::cin >> szBuffer;
- //发送数据
- nRet = send(nClientSocket, szBuffer, strlen(szBuffer), 0);
- if (nRet == SOCKET_ERROR)
- {
- std::cout << "send failed!\n";
- closesocket(nClientSocket);
- WSACleanup();
- return -1;
- }
- memset(szBuffer, 0, sizeof(szBuffer));
- //接收数据
- nRet = recv(nClientSocket, szBuffer, sizeof(szBuffer), 0);
- if (nRet == SOCKET_ERROR)
- {
- std::cout << "recv failed!\n";
- closesocket(nClientSocket);
- WSACleanup();
- return 1;
- }
- std::cout << szBuffer << std::endl;
- }
-
- closesocket(nClientSocket);
- WSACleanup();
-
- return 0;
- }
-
- int sendto(
-
- __in SOCKET s, //指定套接字(可能已连接)
-
- __in const char *buf, //指向将要发送数据的缓冲区
-
- __in int len, //缓冲区大小
-
- __in int flags, //指定数据传输方式
-
- __in const struct sockaddr *to, //可选的指针,指向存储目标套接字地址信息的sockaddr结构
-
- __in int tolen //to参数指向结构的字节大小
-
- );
-
- 返回值:
-
- 成功时,返回发送的字节数;
-
- 失败时,返回SOCKET_ERROR,调用WSAGetLastError函数查看进一步错误信息。
- recvfrom函数用于接收数据报并存储发送方源地址信息:
-
- int recvfrom(
-
- __in SOCKET s, //指定一个绑定的socket
-
- __out char *buf, //存放接到的数据的缓冲区
-
- __in int len, //缓冲区字节大小
-
- __in int flags, //指定传输控制方式
-
- __out struct sockaddr *from, //可选的指针,函数成功返回后,
-
- //指向存储源套接字地址信息的sockaddr结构
-
- __inout_opt int *fromlen //from的字节大小
-
- );
-
- 返回值:
-
- 成功时,返回接收的字节数;
-
- 失败时,返回SOCKET_ERROR,调用WSAGetLastError函数查看进一步错误信息。
- // WinServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
-
- #include "pch.h"
- #include <iostream>
- #include <WinSock2.h>
-
- #pragma comment(lib, "ws2_32.lib")
-
- int main()
- {
- WORD wVersion = MAKEWORD(2, 2);
- WSADATA wsaData = { 0 };
- //WinSocket初始化
- if (WSAStartup(wVersion, &wsaData))
- {
- std::cout << "WSAStartup Error" << std::endl;
- return 1;
- }
-
- //创建socket
- SOCKET nServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (nServerSocket == INVALID_SOCKET)
- {
- std::cout << "create socket Error" << std::endl;
- WSACleanup();//释放WinSocket
- return 1;
- }
-
- sockaddr_in serverAddr = { 0 };
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_port = htons(8888); //绑定端口
- serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //绑定ip
-
- //绑定ip和端口
- if (SOCKET_ERROR == bind(nServerSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)))
- {
- std::cout << "bind Error" << std::endl;
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
- return 1;
- }
-
- sockaddr clientAddr = { 0 };
- int nLen = sizeof(clientAddr);
- char szBuffer[255] = { 0 };
- int nRet = recvfrom(nServerSocket, szBuffer, 255, 0, &clientAddr, &nLen);
- if (nRet)
- {
- std::cout << szBuffer << std::endl;
- }
-
- closesocket(nServerSocket);
- WSACleanup();//释放WinSocket
-
- getchar();
- return 0;
- }
-
- // WinClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
-
- #include "pch.h"
- #include <iostream>
- #include <WS2tcpip.h>
- #include <WinSock2.h>
-
- #pragma comment(lib, "ws2_32.lib")
-
- int main()
- {
- WSADATA wsaData = { 0 };
- SOCKET nClientSocket = { 0 };
-
- //WinSocket初始化
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- std::cout << "WSAStartup failed!\n";
- return 1;
- }
-
- //创建socket
- nClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (nClientSocket == INVALID_SOCKET)
- {
- std::cout << "socket failed!\n";
- //释放
- WSACleanup();
- return 1;
- }
-
- sockaddr_in addrServ = { 0 };
- addrServ.sin_family = AF_INET;
- addrServ.sin_port = htons(8888); //服务器端口
- inet_pton(AF_INET, "127.0.0.1", &addrServ.sin_addr); //服务器ip
-
- char szBuffer[255] = "123456";
- int nRet = sendto(nClientSocket, szBuffer, 255, 0, (sockaddr*)&addrServ, sizeof(addrServ));
- if (nRet)
- {
- std::cout << "send success" << std::endl;
- }
-
- closesocket(nClientSocket);
- WSACleanup();
-
- getchar();
- return 0;
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。