【菜鸡求助,谢谢大佬~】socket通信+线程(代码已贴,研究两天无果 T_T)
client发data的方式不同导致结果不同。发数据的两种方式用感叹号标出了想用循环达到方式2的效果,但是方式1的结果运行的不对。到底哪里错了呢?求指教~~~
client端:
程序代码:
#include <iostream> #include <stdlib.h> #include <stdio.h> #include "winsock2.h" #pragma comment(lib,"ws2_32.lib")//引用库文件 using namespace std; SOCKET sockClient[2]; //新! char recvBuf[2][20];//新! HANDLE hHandle;// HANDLE existHandle[2]; int thread[2]; DWORD WINAPI Fun(LPVOID lp) { int serverId = *(int*)(lp); DWORD hRes = 0; printf("enter Fun,serverId=%d \n", serverId); //用线程接收数据2 if (recv(sockClient[serverId], recvBuf[serverId], sizeof(recvBuf), 0) <= 0) { printf("接受失败"); } else { //printf("recvBuf[%d]=%s\n", serverId, recvBuf[serverId]); //closesocket(sockClient); //发送数据3 char result1[] = "sat"; char result2[] = "unsat"; char buffs1[100] = "satStop"; char buffs2[100] = "unsatGoon"; if (strcmp(recvBuf[serverId], result1) == 0) {//sat printf("recvBuf[%d]=%s\n", serverId, recvBuf[serverId]); for (int i = 0;i < 2;i++) { if (i != serverId) { //server1 sat 则给server2发stop printf("here is sat,send to server%d to stop:%s\n", i, buffs1); send(sockClient[i], buffs1, sizeof(buffs1), 0); //这里是i不是serverId了 } } SetEvent(existHandle[serverId]); } else if (strcmp(recvBuf[serverId], result2) == 0) {//unsat printf("recvBuf[%d]=%s\n", serverId, recvBuf[serverId]); printf("server%d unsat\n", serverId); //printf("here is unsat send to server%d :%s\n", serverId, buffs2); //send(sockClient[serverId], buffs2, sizeof(buffs2), 0); SetEvent(existHandle[serverId]); } else { printf("绝望了\n"); } //closesocket(sockClient[serverId]); return 0; } //closesocket(sockClient); //return 0; } int main() { printf("This is client\n"); //加载套接字 WSADATA wsaData; char buff[1024]; memset(buff, 0, sizeof(buff)); if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("初始化Winsock失败"); return 0; } SOCKADDR_IN addrSrv[2]; //端口号 IP addrSrv[0].sin_family = AF_INET; addrSrv[0].sin_port = htons(8888); addrSrv[0].sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //端口号 IP addrSrv[1].sin_family = AF_INET; addrSrv[1].sin_port = htons(2222); addrSrv[1].sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //SOCKET sockClient[2]; for (int i = 0;i < 2;i++) { //创建套接字 sockClient[i] = socket(AF_INET, SOCK_STREAM, 0); if (SOCKET_ERROR == sockClient[0]) { printf("Socket() error:%d", WSAGetLastError()); return 0; } //向服务器发出连接请求 if (connect(sockClient[i], (struct sockaddr*)&addrSrv[i], sizeof(addrSrv[i])) == INVALID_SOCKET) { printf("server1连接失败:%d", WSAGetLastError()); return 0; } } /** //向server0,server1 发送数据1(方式1)!!!! char databuf[2][100]; string str0 = "000000"; string str1 = "111111"; int length0 = str0.copy(databuf[0], 6); databuf[0][length0] = '\0'; int length1 = str1.copy(databuf[1], 6); databuf[1][length1] = '\0'; for (int i = 0;i < 2;i++) { send(sockClient[i], databuf[i], sizeof(databuf), 0); printf("send to server%d:%s\n", i, databuf[i]); } */ /** //向server0,server1 发送数据1 (方式2)!!!! char databuf0[7] = "000000"; char databuf1[7] = "111111"; send(sockClient[0], databuf0, sizeof(databuf0), 0); send(sockClient[1], databuf1, sizeof(databuf1), 0); */ printf("用线程接收数据\n "); //创建事件 for (int i = 0;i < 2;i++) { existHandle[i] = ::CreateEvent(NULL, FALSE, FALSE, NULL); } HANDLE hThread[8]; //创建两线程 int ID[2]; for (int i = 0;i < 2;i++) { ID[i] = i; hThread[i] = CreateThread(NULL, 0, Fun, &ID[i], 0, NULL); } //等待全部线程运行结束 int cn = 0; while (true) { printf("没wait到呢\n "); DWORD hr = WaitForMultipleObjects((DWORD)2, existHandle, false, INFINITE); if (hr == WAIT_FAILED) { break; printf("hr == WAIT_FAILED\n "); } cn++; printf("1\n "); if (cn >= 2) //两个线程都执行完毕 { printf("主线程要结束了\n "); break; } } //关闭套接字 //closesocket(sockClient[0]); //closesocket(sockClient[1]); WSACleanup();//释放初始化Ws2_32.dll所分配的资源。 system("pause");//让屏幕暂留 return 0; }
server1
程序代码:
#include <iostream> #include <stdlib.h> #include "project.h" #include <stdio.h> #include "winsock2.h" #include<cstdlib> #pragma comment(lib,"ws2_32.lib")//引用库文件 using namespace std; char recvBuf1[49]; short buff[49]; SOCKET sockConn; HANDLE hEvent; DWORD WINAPI Fun(LPVOID lpParamter) { char buff2[100]; char result[] = "satStop"; memset(buff2, 0, sizeof(buff2)); if (recv(sockConn, buff2, sizeof(buff2), 0) < 0) { printf("Receive fail\n"); } else { printf("Receive form client success:%s\n", buff2); if (strcmp(buff2, result) == 0) { SetEvent(hEvent); } return 0; } } int main() { printf("server0 ready\n"); WSADATA wsaData; int port = 8888; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("初始化失败"); return 0; } //创建用于监听的套接字,即服务端的套接字 SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(port); addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //bind int retVal = bind(sockSrv, (LPSOCKADDR)&addrSrv, sizeof(SOCKADDR_IN)); if (retVal == SOCKET_ERROR) { printf("连接失败:%d\n", WSAGetLastError()); return 0; } //listen if (listen(sockSrv, 10) == SOCKET_ERROR) { printf("监听失败:%d", WSAGetLastError()); return 0; } SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); while (1) { //等待客户请求到来 sockConn = accept(sockSrv, (SOCKADDR *)&addrClient, &len); if (sockConn == SOCKET_ERROR) { printf("等待请求失败:%d", WSAGetLastError()); break; } printf("客户端的IP是:[%s]\n", inet_ntoa(addrClient.sin_addr)); //接收confirm recv(sockConn, recvBuf1, sizeof(recvBuf1), 0); cout << recvBuf1; printf("char buff end\n"); //将buf转为short类型 for (int j = 0;j < 48;j++) { buff[j] = recvBuf1[j] - '0'; //cout << "Shh " << buffs[i][j]; printf("buff][%d] = %d", j, buff[j]); printf("\n short buf end\n"); } //将数据赋值给confirm bool isTrue = ConfirmedVar(buff); if (isTrue == 0) { printf("has confirmed"); //printf(ConfirmedVariableAllUnitsAssignment[][]); } //发送数据2 char sendbuf1[] = "unsat"; int Send = send(sockConn, sendbuf1, sizeof(sendbuf1), 0); if (Send == SOCKET_ERROR) { printf("发送失败"); break; } else { printf("unsat发送成功\n"); } hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //使用手动重置为无信号状态,初始化时有信号状态 int id[2]; HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fun, &id[0], 0, NULL); int cn2 = 0; while (true) { printf("没wait到呢\n "); DWORD hr = WaitForSingleObject(hEvent, INFINITE); if (hr == WAIT_FAILED) { break; printf("hr == WAIT_FAILED\n "); } cn2++; printf("cn2=%d\n ", cn2); if (cn2 >= 1) //两个线程都执行完毕 { printf("子线程setEvent了,主线程要结束了\n "); break; } } closesocket(sockConn); }//while closesocket(sockSrv); WSACleanup(); system("pause"); return 0; }
server2
程序代码:
#include <iostream> #include <stdlib.h> #include <stdio.h> #include "winsock2.h" #include<cstdlib> #pragma comment(lib,"ws2_32.lib")//引用库文件 using namespace std; char recvBuf[100]; SOCKET sockConn; HANDLE hEvent; DWORD WINAPI Fun(LPVOID lpParamter) { char buff2[100]; char result[] = "satStop"; memset(buff2, 0, sizeof(buff2)); if (recv(sockConn, buff2, sizeof(buff2), 0) < 0) { printf("Receive fail\n"); } else { printf("Receive form client success:%s\n", buff2); if (strcmp(buff2, result) == 0) { SetEvent(hEvent); } return 0; } return 0; } int main() { printf("This is server 1\n"); WSADATA wsaData; int port = 2222;//端口号 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("初始化失败"); return 0; } //创建用于监听的套接字,即服务端的套接字 SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(port); //1024以上的端口号 addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); int retVal = bind(sockSrv, (LPSOCKADDR)&addrSrv, sizeof(SOCKADDR_IN)); if (retVal == SOCKET_ERROR) { printf("连接失败:%d\n", WSAGetLastError()); return 0; } if (listen(sockSrv, 10) == SOCKET_ERROR) { printf("监听失败:%d", WSAGetLastError()); return 0; } SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); while (1) { //等待客户请求到来 sockConn = accept(sockSrv, (SOCKADDR *)&addrClient, &len); if (sockConn == SOCKET_ERROR) { printf("等待请求失败:%d", WSAGetLastError()); break; } //接收数据1 recv(sockConn, recvBuf, sizeof(recvBuf), 0); printf("Receive form client:%s\n", recvBuf); //发送数据2 char sendbuf1[] = "unsat"; int Send = send(sockConn, sendbuf1, sizeof(sendbuf1), 0); if (Send == SOCKET_ERROR) { printf("发送失败"); break; } hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //使用手动重置为无信号状态,初始化时有信号状态 int id[2]; HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fun, &id[0], 0, NULL); int cn2 = 0; while (true) { printf("没wait到呢\n "); DWORD hr = WaitForSingleObject(hEvent, INFINITE); if (hr == WAIT_FAILED) { break; printf("hr == WAIT_FAILED\n "); } cn2++; printf("cn2=%d\n ", cn2); if (cn2 >= 1) //两个线程都执行完毕 { printf("子线程setEvent了,主线程要结束了\n "); break; } } } closesocket(sockConn); closesocket(sockSrv); WSACleanup(); system("pause"); return 0; }