想到一个socket在多线程模式下,是否可以同时使用的问题,比如socket A阻塞在recv,而别的线程用socket A send是否能成功,下面上实验代码
1 void thread_socket(int socket) 2 { 3 Sleep(2000); 4 int error = send(socket, "asd", strlen("asd"), 0); 5 6 char recData[255] = {0}; 7 //setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(int)); 8 int ret = recv(socket, recData, 255, 0); 9 getchar(); 10 } 11 int main() 12 { 13 unsigned short port = 57001; 14 15 char ch1[10] = { 1,2,3,4 }; 16 memcpy(ch1, &port, 2); 17 string s1; 18 s1= string(ch1, 20); 19 string s("123", 2); 20 unsigned short unsi = 65510; 21 char *ch = ((char*)&unsi); 22 23 char ccc[2] = {0}; 24 unsigned short t = *((unsigned short *)(ch)); 25 26 WORD sockVersion = MAKEWORD(2, 2); 27 WSADATA data; 28 if (WSAStartup(sockVersion, &data) != 0) 29 { 30 return 0; 31 } 32 sockaddr_in serAddr; 33 serAddr.sin_family = AF_INET; 34 serAddr.sin_port = htons(8888); 35 inet_pton(AF_INET, "127.0.0.1", &serAddr.sin_addr); 36 37 while (true) 38 { 39 SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 40 if (sclient == INVALID_SOCKET) 41 { 42 printf("invalid socket!"); 43 return 0; 44 } 45 if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) 46 { //连接失败 47 printf("connect error !"); 48 closesocket(sclient); 49 return 0; 50 } 51 send(sclient, "asd", strlen("asd"), 0); 52 char recData[255]; 53 int nNetTimeout = 5000; 54 /*setsockopt(sclient, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int));*/ 55 56 int opt_val; 57 socklen_t opt_len = sizeof(opt_val); 58 //getsockopt(sclient, IPPROTO_TCP, SO_SNDBUF, (char *)&opt_val, (socklen_t *)&opt_len); 59 60 std::thread t(thread_socket, sclient); 61 int i = 2; 62 while (i--) 63 { 64 int ret = recv(sclient, recData, 255, 0); 65 if (ret > 0) { 66 recData[ret] = 0x00; 67 printf(recData); 68 } 69 } 70 closesocket(sclient); 71 } 72 WSACleanup(); 73 return 0; 74 }
经过实验发现,socket A阻塞在recv,而别的线程用socket A send是可以成功的。
还有个发现,当一个socket被多出recv时,内核返回时会回调最先调用recv的地方