一.win32的socket编程,是socket编程中比较经典也比较基础的一部分,根据传输方式和协议的区别,可以简单的分为TCP传递和UDP传递两种。这篇文章主要是阐述基于TCP的Socket编程。
二.Socket相关API
1.WSAStartup
int WSAStartup( __in WORD wVersionRequested, __out LPWSADATA lpWSAData );
这个函数是用来加载Winsocket DLL,wVersionRequested是用来存储你所要申请的Winsocket DLL版本,可以通过MAKEWORD函数获取,wVersionRequested的高位代表副版本号,低位代表高版本号。
附注:
WORD MAKEWORD( BYTE bLow, BYTE bHigh );
2.bind
int bind( SOCKET s, const struct sockaddr FAR* name, int namelen );
将套接字绑定于特定地址的特定端口,其中第二个参数可以使用SOCKADDR_IN来代替。
附注:
struct sockaddr_in{short sin_family; //该参数在因特网下必须为AF_INETunsigned short sin_port;struct in_addr sin_addr;//IP地址,可以通过inet_addr函数转换得到,服务器端也可以直接设定为INADDR_ANYchar sin_zero[8]; };//需要注意的是这里除了第一个参数外,其他数据均应为网络格式,应该使用htonl或者htons进行转换
3.listen
int listen(__in SOCKET s,__in int backlog );
这个函数一般用于服务器端,这里的第二个参数为请求队列的最大程度,注意,不是最大连接数目
4.accept
SOCKET accept(SOCKET s,struct sockaddr FAR* addr,int FAR* addrlen );
accept一样主要用于服务器端,第二个参数同样可以使用SOCKADDR_IN来替代,但是注意,这里,该参数是用来存储建立连接时候客户端的相关信息。
5.connect
int connect(SOCKET s,const struct sockaddr FAR* name,int namelen );
这个函数用于客户端,当客户端向服务器端发出请求建立连接时候使用,第二个参数可以使用SOCKADDR_IN来替代,但是注意,这里,该参数是用来存储建立连接时候服务器端的相关信息。
6.send
int send(SOCKET s,const char FAR* buf,int len,int flags );
该函数用来相互发送数据,但是需要注意的是,服务器端使用该函数时候,第一个参数为accept函数所返回的socket结构值。
7.recv
int recv(__in SOCKET s,__out char* buf,__in int len,__in int flags );
该函数与send函数类似,我就不再赘述。
三.一个简单示例
服务器端
#include<WinSock2.h> #include <stdio.h> void main() {WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) {return;}if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 ) {WSACleanup();return; }SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));listen(sockSrv,5);SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);while (1){SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);char sendbuffer[100];sprintf(sendbuffer,"Welcome %s here",inet_ntoa(addrClient.sin_addr));send(sockConn,sendbuffer,strlen(sendbuffer)+1,0);char recvchar[100];recv(sockConn,recvchar,100,0);printf("%s\n",recvchar);closesocket(sockConn);}}
客户端
#include<WinSock2.h> #include <stdio.h> void main(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) {return;}if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 ) {WSACleanup();return; }SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);connect(sockClient,(SOCKADDR *)&addrSrv,sizeof(SOCKADDR));char recvBuffer[100];recv(sockClient,recvBuffer,100,0);printf("%s\n",recvBuffer);send(sockClient,"This is Kary",strlen("This is Kary")+1,0);closesocket(sockClient);WSACleanup();}