Windows Socket+TCPserverclient
Winsock是 Windows下套接字标准。
Socket套接字基于计算机网络,提供同一系统上不同进程或由局域网连接在一起的不同机器上的进程间通讯功能。
例如以下图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG92ZWNvZGVsZXNz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
套接字通过IP地址,Portport号标识,通过这个标识能够在整个局域网定位一个套接字。通过套接字进程便能够相互数据传输。如:进程A与进程B之间欲通过套接字通信,首先进程A创建一个有IP地址,port号唯一标识的套接字,进程B相同创建一个有IP地址,port号唯一标识的套接字,进程A。B便能够通过对方套接字发送与接收信息。
TCP提供是可靠的传输数据服务,通过TCP套接口函数使用。
1.库支持:
Winsock
API 函数由WS2_32.DLL支持,可通过WS2_32.LIB訪问。
API 函数由WS2_32.DLL支持,可通过WS2_32.LIB訪问。
Windows socket编程前须要初始化WS2_32.DLL。通过han函数WSAStartup完毕初始化。
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") //静态载入ws2_32.lib
WS2_32.DLL 初始化:
int WSAStartup(WORD wVersionRequested,LPWSADATA
lpWSAData);
lpWSAData);
该函数第一个參数为WS2_32.DLL版本号,通常设为MAKEWORD(2,0)。第二个參数为一个指向WSADATA的指针,用于返回WS2_32.DLL的配置信息。Socket编程前须要调用该函数。
WS2_32.DLL 释放:
int WSACleanup(
);
);
该函数用于释放WS2_32.DLL。不须要Winsock功能时调用该函数。
2.TCP基本函数:
创建socket:
SOCKET socket (int af, int type,
int protocol);
int protocol);
第一个參数af: 表示族地址,网络编程一般使用AF_INET宏。
第二个參数type: 表示连接类型。TCP选面向连接SOCK_STREAM,UDP选数据报SOCK_DGRAM。
第三个參数protocol: 表示协议,使用AF_INET族地址TCP连接时,设为IPPROTO_TCP。
绑定socket:
int bind(SOCKET
s, const struct sockaddr *saddr,int namelen);
s, const struct sockaddr *saddr,int namelen);
第一个參数: 须要绑定的socket。
第二个參数: 相应AF_INET。使用struct sockaddr_in包括协议,IP。port等信息。
第三个參数: 相应AF_INET。使用struct sockaddr_in结构大小。
该函数将socket与协议,IP,port号绑定起来,相对于给socket“命名”唯一的标识。这样其它的进程就能够通过这个标识找到这个socket。
监听socket:
int listen(SOCKET
s, int nQueueSize);
s, int nQueueSize);
第一个參数: 监听的socket。
第二个參数: 套接字监听队列最大连接请求数。
该函数将监听对socket的连接请求。
请求连接:
int connect(SOCKET
s,const struct sockaddr *saddr,int namelen) ;
s,const struct sockaddr *saddr,int namelen) ;
第一个參数: socket本地进程的socket。
第二个參数: 相应AF_INET,对方IP,port等socket地址标识sockaddr_in。
第三个參数: 相应AF_INET,使用sockaddr_in结构大小。
接受连接请求:
SOCKET accept(SOCKET
s, struct sockaddr *addr, int *addrlen);
s, struct sockaddr *addr, int *addrlen);
第一个參数: socket为被监听的socket。
第二个參数: 相应AF_INET,一个sockaddr指针。将写入发送请求方的sockaddr_in信息。
第三个參数: 相应AF_INET,sockaddr_in结构体的大小。
该函数用于接受一个socket连接请求,返回一个新的连接socket(实质是请求方的socket)。发送与接收数据通过这个连接套socket。
发送数据:
int send(SOCKET
s, const char *buf, int len, int flags );
第一个參数: socket为对方的socket。
第二个參数: 发送数据的缓冲区。
第三个參数: 数据缓冲区大小。
第四个參数: 紧急状态。一般这为0。
该函数用于向对方socket发送数据。成功返回发送数据的大小数。
发送数据:
int recv(SOCKET
s, char *buf, int len, int flags);
第一个參数: socket为对方的socket。
第二个參数: 接收数据的缓冲区。
第三个參数: 缓冲区大小。
第四个參数: 紧急状态。一般这为0。
该函数用于接收对方发送的数据。成功返回发送数据的大小数。
关闭套接字:
int closesocket(SOCKET
s);
s);
參数为socket。
该函数用于关闭套接字。
3.牛刀小试:
VC6.0中,先执行TCPserver程序,再打开一个VC6.0,执行TCPclient程序。
执行效果:
server端程序:
client程序: