初步研究了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模型編程流程如下圖:
返回欄目頁:http://www.bianceng.cn/Programming/cplus/
Socket的服務器段詳細注釋代碼:
// server6.cpp : Defines the entry point for the console application. // //TcpServer.cpp #include <winsock2.h> #include <stdio.h> #pragma comment(lib,"ws2_32.lib") #include <iostream> using namespace std; void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//SDK這個宏創建一個無符號16位整形,通過連接兩個給定的無符號參數。表示1.1版本 err = WSAStartup( wVersionRequested, &wsaData );//通過WSAStartup函數完成對Winsock服務的初始化,調用socket必須初始化 if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )//如果版本錯誤返回 { WSACleanup( );//釋放WSAStartup return; } SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0); //建立本地流式套接字,返回套接字號;af_inet地址族,用流式套接字,自動匹配 SOCKADDR_IN addrSrv;//TCP/IP的地址信息 addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//允許套接字向任何分配給本地機器的IP地址發送或接收數據。 addrSrv.sin_family = AF_INET;//TCP指定的 addrSrv.sin_port = htons(6000);//端口號 bind(sockSrv,(sockaddr*)&addrSrv,sizeof(SOCKADDR));//綁定套接字 listen(sockSrv,5);//#####監聽本地套接字 SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); char revBuf[100],sendBuf[100]; while(1) { SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len);//接受鏈接等待客戶端鏈接,返回客戶套接字 char sendBuf[100]; cout<<"我說:\n"; //sprintf(sendBuf,"Welcome %s to chat with me!",inet_ntoa(addrClient.sin_addr)); cin>>sendBuf; send(sockConn,sendBuf,strlen(sendBuf)+1,0); recv(sockConn,revBuf,100,0); cout<<"對方說:\n"; printf("%s\n",revBuf); memset(revBuf,0,100); closesocket(sockConn); } closesocket(sockSrv); }
Socket的客戶端詳細注釋代碼:
//TcpClient.cpp #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") #include <iostream> using namespace std; 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");//"49.152.49.84"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//連接到目的主機 char recvBuf[100],sendBuf[100]; while (true) { recv(sockClient,recvBuf,100,0); cout<<"對方說:"; printf("%s\n",recvBuf); memset(recvBuf,0,100); cout<<"我說:"; cin>>sendBuf; send(sockClient,sendBuf,strlen(sendBuf)+1,0); } closesocket(sockClient);//關閉套接字 WSACleanup(); }
作者:cnblogs zCoderJoy