一.win32的socket編程,是socket編程中比較經典也比較基礎的一部分,根據傳輸方式和協議的區別,可以簡單的分為TCP傳遞和UDP傳遞兩種。這篇文章主要是闡述基於TCP的Socket編程。
二.Socket相關API
1.WSAStartup
int WSAStartup(<br /> __in WORD wVersionRequested,<br /> __out LPWSADATA lpWSAData<br />);
這個函數是用來載入Winsocket DLL,wVersionRequested是用來儲存你所要申請的Winsocket DLL版本,可以通過MAKEWORD函數擷取,wVersionRequested的高位代表副版本號碼,低位代表高版本號碼。
附註:
WORD MAKEWORD(<br /> BYTE bLow,<br /> BYTE bHigh<br />);</p><p>
2.bind
int bind(<br /> SOCKET s,<br /> const struct sockaddr FAR* name,<br /> int namelen<br />);<br />
將通訊端綁定於特定地址的特定連接埠,其中第二個參數可以使用SOCKADDR_IN來代替。
附註:
struct sockaddr_in{ short sin_family; //該參數在網際網路下必須為AF_INET unsigned short sin_port; struct in_addr sin_addr; //IP地址,可以通過inet_addr函數轉換得到,伺服器端也可以直接設定為INADDR_ANY char 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();}