我正在尝试在同一程序中构建客户端和服务器。例如,用户1将数据包发送给用户2,用户2在收到数据包后将另一个数据包发回给用户1。问题是,运行该程序后,两个用户都没有收到该数据包。与服务器正常工作的程序分开
#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <thread>
static const int num_threads = 2;
static char buffer[8096 + 1];
char a[256] = {};
char MOTD[256];
void call_from_thread(int tid) {
// ---------- Server code: ---------- //
if( tid == 0 ){
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0){MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);}
SOCKADDR_IN addr;
int addrlen = sizeof(addr);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(1112);
addr.sin_family = AF_INET;
SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
listen(sListen, SOMAXCONN);
SOCKET newConnection;
newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
if (newConnection == 0){
std::cout << "Failed to accept the client's connection." << std::endl;
}else{
std::cout << "Client Connected!" << std::endl;
}
while (true){
std::cin >> a;
send(newConnection, a, sizeof(a), NULL);
}
}else if( tid == 1 ){
// ---------- Client code: ---------- //
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0){MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);}
SOCKADDR_IN addr;
int sizeofaddr = sizeof(addr);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(1111);
addr.sin_family = AF_INET;
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
{
MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
//return 0; //Failed to Connect
}
std::cout << "Connected!" << std::endl;
char MOTD[256];
while (true){
recv(Connection, MOTD, sizeof(MOTD), NULL); //Receive Message of the Day buffer into MOTD array
std::cout << "MOTD:" << MOTD << std::endl;
}
}
// ---------- Thread selection: ---------- //
int main() {
std::thread t[num_threads];
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
for (int i = 0; i < num_threads; ++i) {
t[i].join();
}
}
答案 0 :(得分:1)
服务器正在侦听端口1112,但是客户端正在连接端口1111。这意味着客户端和服务器之间可能根本无法相互连接,无论它们是否在同一应用程序中。
我还看到了您的代码的许多其他问题,包括:
WSAStartup()
应该在应用启动时被调用一次,而不是每个线程被调用。
如果任何WinSock函数失败,则两个线程都不能干净退出。
在客户端可以连接到它之前,客户端线程不等待服务器线程打开其侦听端口。
潜在的缓冲区溢出。
资源泄漏。
缺乏体面的错误处理。
socket()
,bind()
,listen()
和send()
报告的错误,并且您没有检查{的返回值{1}}正确。accept()
和socket()
报告的错误。而且,在将recv()
缓冲区打印到MOTD
之前,不能确保其为空终止。尝试更多类似的方法:
std::cout