標籤:style blog http color io os 使用 ar for
剛剛接觸SOCKET編程,網上看了一些資料,發現做些簡單的應用還是不難。但是要深入瞭解SOCKET編程還需要系統的看一些書。一般在處理序間通訊TCP是一種不錯的方式。 ---XXX
TCP連結是面向流的連結,因此資料在應用程式看來應該是沒有邊界的,之前對send和recv函數中發送的大小和傳回值沒有理解,今天做了一個實驗有了進一步的瞭解。socket一些常用的函數介紹可以在這裡找到http://blog.csdn.net/ithzhang/article/details/8448655
之前有個疑問是如果一方向另一方一次發送大量的資料,超過了TCP緩衝區的大小,那麼接收方該如何處理。這裡就要用到recv函數的傳回值了,它指示了本次調用函數實際接收的位元組數,如果這個值小於我們需要接收的資料,那麼就需要再一次調用recv函數。
下面是我測試的代碼,代碼是在VS2013下編譯的。
歡迎一起討論,指正錯誤。
伺服器端:
1 #include <winsock2.h> 2 #include <iostream> 3 #include <numeric> 4 #include <vector> 5 #include <algorithm> 6 #pragma comment(lib,"ws2_32.lib") 7 8 9 using namespace std;10 11 const int port = 2048;12 13 int main(int argc,char**argv)14 {15 WSADATA ws;16 if (WSAStartup(MAKEWORD(2, 2), &ws) != 0)17 {18 cout << "init windows socket failed::" << GetLastError() << endl;19 return -1;20 }21 22 SOCKET serverSocket;23 24 serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);25 26 sockaddr_in serverAddr;27 serverAddr.sin_family = AF_INET;28 serverAddr.sin_port = htons(port);29 //serverAddr.sin_addr.s_addr = inet_addr("192.168.182.1");30 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);31 memset(&(serverAddr.sin_zero), 0, sizeof(serverAddr.sin_zero));32 33 if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr))!=0)34 {35 cout << "bind server socket failed\n";36 WSACleanup();37 return -1;38 }39 40 if (listen(serverSocket,10)!=0)41 {42 cout << "listen failded\n";43 return -1;44 }45 46 const int buf_size = 1024 * 1024;47 48 float *buf = new float[buf_size]; 49 50 for_each(buf, buf + buf_size, [](float &v){v = 1; });51 cout << std::accumulate(buf, buf + buf_size, 0) << endl;52 while (true)53 {54 int add_size = sizeof(SOCKADDR);55 56 sockaddr_in client_addr;57 SOCKET accept_sock = accept(serverSocket, (SOCKADDR*)&client_addr, &add_size);58 if (accept_sock == -1)59 {60 cout << "accept faild\n";61 continue;62 }63 64 int send_size = send(accept_sock, (char*)buf, buf_size*sizeof(float), 0);65 cout << send_size << endl;66 if (send_size==-1)67 {68 cout << "send data faild\n";69 continue;70 }71 72 }73 74 delete[] buf;75 return 0;76 }View Code
用戶端的:
1 #include <iostream> 2 #include <numeric> 3 #include <winsock2.h> 4 #include <algorithm> 5 6 #pragma comment(lib,"ws2_32.lib") 7 using namespace std; 8 const int port = 2048; 9 int main()10 {11 WSADATA ws;12 13 if (WSAStartup(MAKEWORD(2, 2), &ws) != 0)14 {15 cout << "load socket faild\n";16 WSACleanup();17 return -1;18 }19 20 SOCKET client_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);21 22 sockaddr_in server_addr;23 server_addr.sin_family = AF_INET;24 server_addr.sin_port = htons(port);25 server_addr.sin_addr.s_addr = inet_addr("192.168.182.1");26 memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));27 28 if (connect(client_sock, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) != 0)29 {30 cout << "connect to server failed \n";31 WSACleanup();32 return -1;33 }34 const int buf_size = 1024 * 1024;35 36 float *buf = new float[buf_size] ;37 for_each(buf, buf + buf_size, [](float &v){v = 0; });38 cout << std::accumulate(buf, buf + buf_size, 0) << endl;39 40 int recved_size = 0;41 42 do 43 {44 int rsz = recv(client_sock, (char*)buf + recved_size, buf_size*sizeof(float)-recved_size, 0);45 if (rsz == -1)46 {47 cout << "recv data failed\n";48 WSACleanup();49 }50 recved_size += rsz;51 52 } while (recved_size<buf_size*sizeof(float));53 54 cout << std::accumulate(buf, buf + buf_size, 0) << endl;55 delete[] buf;56 57 58 closesocket(client_sock);59 }View Code
使用SOCKET TCP