多线程客户端未从服务器接收消息
Multi-threaded client not receiving messages from server
我有一个多客户端服务器程序。客户端控制台需要等待用户输入消息以发送到服务器,并且客户端还需要始终可用于从服务器接收消息(这种情况间歇性地发生(。为此,我尝试在客户端设置两个线程,一个用于接收,一个用于发送。
最初,客户端程序(我从这里下载(旨在向服务器发送消息并立即接收消息。这是初始代码(我在这里没有包含函数,因为我知道它们有效,并且函数名称是不言自明的(:
int main()
{
//initialize the winsock library
myTcpSocket::initialize();
//get client's information
string clientName = clientInfo.getHostName();
string clientIPAddress = clientInfo.getHostIPAddress();
//get server's IP address and name
string serverIPAddress = "";
readServerConfig(serverIPAddress);
myHostInfo serverInfo(serverIPAddress,ADDRESS);
string serverName = serverInfo.getHostName();
//create the socket for client
myTcpSocket myClient(PORTNUM);
// connect to the server.
myClient.connectToServer(serverIPAddress, ADDRESS);
int recvBytes = 0;
while (1)
{
// send message to server
char messageToServer[MAX_MSG_LEN+1];
memset(messageToServer, 0, sizeof(messageToServer));
cout << "[SEND] ";
cin.getline(messageToServer,MAX_MSG_LEN);
winLog << "[SEND] " << messageToServer << endl;
myClient.sendMessage(string(messageToServer));
if ( !string(messageToServer).compare("Quit") || !string(messageToServer).compare("quit") )
break;
//receive message from server
string messageFromServer = "";
recvBytes = myClient.receiveMessage(messageFromServer);
if ( recvBytes == -99 ) break;
cout << "[RECV:" << serverName << "]: " << messageFromServer << endl;
winLog << "[RECV:" << serverName << "]: " << messageFromServer << endl;
}
return 1;
}
这段代码有效,但由于服务器在收到消息时并不总是有消息要发送回客户端,这会阻碍客户端的进程,这就是为什么我使用如下多线程结构(由于上述原因不包括函数(,将接收和发送函数分成不同的线程:
DWORD WINAPI sendHandleThread(LPVOID threadInfo) //sending thread
{
//this structure contains all the data this callback will work on
myThreadArgument* sendArgument = (myThreadArgument*)threadInfo;
//create the socket for client
myTcpSocket myClient(PORTNUM); //PORTNUM = 1200
// connect to the server.
string serverIPAddress = "";
readServerConfig(serverIPAddress);
myClient.connectToServer(serverIPAddress, ADDRESS);
myHostInfo serverInfo(serverIPAddress,ADDRESS);
string serverName = serverInfo.getHostName();
int recvBytes = 0;
while (1)
{
// send message to server
char messageToServer[MAX_MSG_LEN+1];
memset(messageToServer, 0, sizeof(messageToServer));
cout << "[SEND] ";
cin.getline(messageToServer,MAX_MSG_LEN);
winLog << "[SEND] " << messageToServer << endl;
myClient.sendMessage(string(messageToServer));
if ( !string(messageToServer).compare("Quit") || !string(messageToServer).compare("quit") )
break;
}
return 1;
}
DWORD WINAPI recHandleThread(LPVOID threadInfo) //receiving thread
{
//this structure contains all the data this callback will work on
myThreadArgument* recArgument = (myThreadArgument*)threadInfo;
//create the socket for client
myTcpSocket myClient(PORTNUM); //PORTNUM = 1200
// connect to the server.
string serverIPAddress = "";
readServerConfig(serverIPAddress);
myClient.connectToServer(serverIPAddress, ADDRESS);
myHostInfo serverInfo(serverIPAddress,ADDRESS);
string serverName = serverInfo.getHostName();
int recvBytes = 0;
while (1)
{
//receive message from server
string messageFromServer = "";
recvBytes = myClient.receiveMessage(messageFromServer);
if ( recvBytes == -99 ) break;
cout << "[RECV:" << serverName << "]: " << messageFromServer << endl;
winLog << "[RECV:" << serverName << "]: " << messageFromServer << endl;
}
return 1;
}
int main()
{
//semaphore
mySemaphore coutSemaphore(string(""), 1);
//initialize the winsock library
myTcpSocket::initialize();
//get client's information (assume neither the name nor the address is given)
string clientName = clientInfo.getHostName();
string clientIPAddress = clientInfo.getHostIPAddress();
//get server's IP address and name
string serverIPAddress = "";
readServerConfig(serverIPAddress);
myHostInfo serverInfo(serverIPAddress,ADDRESS);
string serverName = serverInfo.getHostName();
//create sending thread
myTcpSocket send;
string sendName = "sendName";
myThreadArgument* sendArgument = new myThreadArgument(&send, &coutSemaphore, sendName);
myThread* sendThread = new myThread(sendHandleThread, (void*)sendArgument);
sendThread->execute();
//create receiving thread
myTcpSocket rec;
string recName = "recName";
myThreadArgument* recArgument = new myThreadArgument(&rec, &coutSemaphore, recName);
myThread* recThread = new myThread(recHandleThread, (void*)recArgument);
recThread->execute();
while (1)
{
//dummy process
Sleep(30000);
cout << "--" << endl;
}
return 1;
}
我已经测试了我已经正确设置了线程 - 但只有我的发送线程有效,即当用户输入消息时,它将被发送到服务器并由服务器接收。但是,我似乎无法从我的服务器收到消息。
我是新手 - 我做错了什么吗?抱歉,如果问题不够清楚 - 我不知道还需要什么。
我的服务器代码的相关片段在这里供参考(我不知道是否需要更多,因为服务器部分似乎按照我需要的方式工作( - 目前我已经设置了它进行测试,以便当它收到来自客户端的消息时,它会立即"回复"(以便我可以在我的客户端上测试接收线程(。随后,它不会立即回复,但只有在有消息要传递给客户端时才回复。
DWORD WINAPI clientHandleThread(LPVOID threadInfo)
{
// this structure will contain all the data this callback will work on
myThreadArgument* clientArgument = (myThreadArgument*)threadInfo;
// get the client connection: receiving messages from client and
// sending messages to the client will all be done by using
// this client connection
myTcpSocket* clientConnection = clientArgument->getClientConnect();
string clientName = clientArgument->getHostName();
// the server is communicating with this client here
while(1)
{
string messageFromClient = "";
// receive from the client
int numBytes = clientConnection->recieveMessage(messageFromClient);
if ( numBytes == -99 ) break;
cout << "[RECV fr " << clientName << "]: " << messageFromClient << endl;
// if the client wants to disconnect
if ( messageFromClient.compare("quit") == 0 || messageFromClient.compare("Quit") == 0 )
{
break;
}
else // send to the client
{
clientConnection->sendMessage(string("testing")); //test reply
}
}
// if we reach here, this session with the client is done,
// so we set the event on this thread to inform the main
// control that this session is finished
clientArgument->getExitEvent()->setEvent();
return 1;
}
在多线程程序中,您正在创建两个客户端,一个在sendHandleThread
中,另一个在recHandleThread
中,并因此具有两个连接。当然,服务器通过客户端消息进入的连接发送其回复消息,即发送到sendHandleThread
,后者不准备接收它,而recHandleThread
通过其连接不接收任何内容,因为没有发送任何内容。若要纠正此问题,必须仅创建一个客户端连接,并让两个线程使用相同的连接。
- 从服务器传输到客户端的消息不会出现
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- 来自带有mbedtls TLS的Mongoose Web服务器的错误消息
- C++ UDP 服务器在获取客户端地址配置时发送消息
- 如何使用标准库网络 TS 在服务器和客户端之间发送消息C++
- 客户端发送消息,但服务器在客户端结束程序之前不接收消息
- 使 gRPC 客户端处于侦听模式,以侦听来自服务器的消息
- 浏览器将随机HTTP消息正文发送到我的boost.asio服务器.我可以更改此设置吗?
- 多线程套接字编程服务器仅从 1 个客户端线程获取消息
- 将 API 链接消息解析为 C (Arduino IDE) 中的服务器
- 无法使用C#TCP服务器和C TCP客户端接收消息
- Datagram套接字服务器未从客户端接收消息
- boost/asio:非常简单的聊天服务器无法访问收到的消息
- 服务器进程等待客户端输入/消息的最佳方法是什么?
- 为什么我的android客户端无法接收到来自winsock c++服务器的字符串消息
- C 客户端和Java服务器消息
- 将消息从C 服务器发送到Java客户端
- 如何从main(winsock)向服务器发送消息
- ZeroMQ C#客户端不接收来自C++服务器的消息
- 如何使用套接字实现服务器客户端编程,在套接字中服务器向客户端发送消息而不从客户端获取请求