初步研究了win32平台的Windows Sockets,它是Microsoft Windows的网络程序设计接口,它是从Berkeley Sockets扩展而来的,以动态链接库的形式提供给我们使用。包括流式套接字(提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收。)和数据报套接字(提供无连接服务。数据包以独立包形式发送,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。)、原始套接字。
CS模型:在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式(client/server),即客户向服务器提出请求,服务器接收到请求后,提供相应的服务。
基于TCP(面向连接)的socket编程:
Sever服务器端程序: 1、创建套接字(socket)。 2、将套接字绑定到一个本地地址和端口上(bind)。 3、将套接字设为监听模式,准备接收客户请求(listen)。 4、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。 5、用返回的套接字和客户端进行通信(send/recv)。 6、返回,等待另一客户请求。 7、关闭套接字。
Client客户端程序: 1、创建套接字(socket)。 2、向服务器发出连接请求(connect)。 3、和服务器端进行通信(send/recv)。 4、关闭套接字。
TCP/IP模型编程流程如下图:
Socket的服务器段详细注释代码:
1 // server6.cpp : Defines the entry point for the console application. 2 // 3 //TcpServer.cpp 4 #include <winsock2.h> 5 #include <stdio.h> 6 #pragma comment(lib,"ws2_32.lib") 7 #include <iostream> 8 using namespace std; 9 void main() 10 { 11 WORD wVersionRequested; 12 WSADATA wsaData; 13 int err; 14 wVersionRequested = MAKEWORD( 1, 1 );//SDK这个宏创建一个无符号16位整形,通过连接两个给定的无符号参数。表示1.1版本 15 err = WSAStartup( wVersionRequested, &wsaData );//通过WSAStartup函数完成对Winsock服务的初始化,调用socket必须初始化 16 if ( err != 0 ) { 17 return; 18 } 19 if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )//如果版本错误返回 20 { 21 WSACleanup( );//释放WSAStartup 22 return; 23 } 24 SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0); //建立本地流式套接字,返回套接字号;af_inet地址族,用流式套接字,自动匹配 25 SOCKADDR_IN addrSrv;//TCP/IP的地址信息 26 addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//允许套接字向任何分配给本地机器的IP地址发送或接收数据。 27 addrSrv.sin_family = AF_INET;//TCP指定的 28 addrSrv.sin_port = htons(6000);//端口号 29 bind(sockSrv,(sockaddr*)&addrSrv,sizeof(SOCKADDR));//绑定套接字 30 listen(sockSrv,5);//#####监听本地套接字 31 SOCKADDR_IN addrClient; 32 int len = sizeof(SOCKADDR); 33 char revBuf[100],sendBuf[100]; 34 35 while(1) 36 { 37 SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len);//接受链接等待客户端链接,返回客户套接字 38 char sendBuf[100]; 39 cout<<"我说: "; 40 //sprintf(sendBuf,"Welcome %s to chat with me!",inet_ntoa(addrClient.sin_addr)); 41 cin>>sendBuf; 42 send(sockConn,sendBuf,strlen(sendBuf)+1,0); 43 44 45 recv(sockConn,revBuf,100,0); 46 cout<<"对方说: "; 47 printf("%s ",revBuf); 48 memset(revBuf,0,100); 49 closesocket(sockConn); 50 } 51 closesocket(sockSrv); 52 }
Socket的客户端详细注释代码:
1 //TcpClient.cpp 2 #include <stdio.h> 3 #include <winsock2.h> 4 #pragma comment(lib,"ws2_32.lib") 5 #include <iostream> 6 using namespace std; 7 void main() 8 { 9 WORD wVersionRequested; 10 WSADATA wsaData; 11 int err; 12 wVersionRequested = MAKEWORD( 1, 1 ); 13 err = WSAStartup( wVersionRequested, &wsaData );//初始化 14 if ( err != 0 ) 15 { 16 return; 17 } 18 if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 ) 19 { 20 WSACleanup( ); 21 return; 22 } 23 SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);//建立套接字 24 SOCKADDR_IN addrSrv; 25 addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//"49.152.49.84"); 26 addrSrv.sin_family = AF_INET; 27 addrSrv.sin_port = htons(6000); 28 connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//连接到目的主机 29 char recvBuf[100],sendBuf[100]; 30 while (true) 31 { 32 33 recv(sockClient,recvBuf,100,0); 34 cout<<"对方说:"; 35 printf("%s ",recvBuf); 36 memset(recvBuf,0,100); 37 cout<<"我说:"; 38 cin>>sendBuf; 39 send(sockClient,sendBuf,strlen(sendBuf)+1,0); 40 } 41 42 closesocket(sockClient);//关闭套接字 43 WSACleanup(); 44 }
整理以上,供参考。