我有一个多客户端服务器程序。客户端控制台需要等待用户输入消息才能发送到服务器上,并且客户端也需要始终可用于从服务器接收消息(这是间歇性发生的)。为了做到这一点,我试图在客户端建立两个线程,一个用于接收,另一个用于发送。多线程客户端未收到来自服务器的消息
最初,客户端程序(我从here下载)旨在向服务器发送消息并立即收到消息。这是最初的代码(我没有包括的功能在这里,因为我知道他们的工作,和函数名是不言自明):
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;
}
我的猜测是服务器可能没有向您的客户端发送任何东西,或者它没有发送recieveMessage()所期望的数据格式。 recieveMessage()在返回之前期望接收多少个字节?它实际接收了多少字节?您可能希望在recieveMessage()实现中放置一些printf以查看那里正在发生的事情......或运行WireShark以查看实际从服务器进入计算机的字节,或者两者都有... – 2013-03-01 02:37:38
服务器_is_发送消息给客户端(如果接收和发送功能都在同一个线程中,我可以收到它),只有当它们被分离到不同的线程中时,程序看起来不会收到任何东西 – sccs 2013-03-01 02:43:45
服务器正在发送当两个函数在同一个线程中时,消息传递给客户端。当函数处于不同的线程中时,你是如何演示它向客户端发送消息的? – 2013-03-01 16:30:39