我在C中有一个必须读取数据并处理它的服务器端应用程序。现在它处理两条消息:将屏幕截图发送到客户端并单击鼠标。在调试时我发现它在客户端询问屏幕截图时收到16个字节,但是当我发送单击鼠标消息时,服务器收到32个字节并挂起。为什么会发生这种情况以及如何正确处理所有传入的数据包?我是winsock的新手,并没有太多解释信息或示例如何处理野外数据。这是服务器的主要代码:
struct coord
{
int x;
int y;
};
struct send_packet
{
int magic;
int cmd;
coord Coords;
};
struct recv_packet
{
int magic;
int code;
int length;
BYTE body[0];
};
do
{
ZeroMemory(&buff, BUFLEN);
int numRcvBytes = 0;
while (numRcvBytes < sizeof(send_packet))
{
iResult = recv(ClientSocket, buff + numRcvBytes, BUFLEN, 0);
//if (iResult <= 0)
// closesocket(ClientSocket);
if (iResult == SOCKET_ERROR)
{
printf("Error %d", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
}
numRcvBytes += iResult;
}
numRcvBytes = 0;
if (iResult > 0)
{
send_packet *pkt;
pkt = (send_packet *)buff;
printf("magc %d cmd %d\n", pkt->magic, pkt->cmd);
printf("Received %d %s\n", iResult, buff);
printf("m:%d c:%d x:%d y:%d\n", pkt->magic, pkt->cmd, pkt->Coords.x, pkt->Coords.y);
int command = pkt->cmd;
recv_packet *rcv_pkt;
int buff_size = 0;
BYTE *data_buffer = NULL;
int size;
int coordX;
int coordY;
wchar_t message[512];
switch (command)
{
case GET_SCREEN:
data_buffer = GetScreeny(75, &buff_size);
rcv_pkt = (recv_packet *)malloc(sizeof(recv_packet)+buff_size);
rcv_pkt->magic = MAGIC;
rcv_pkt->code = 0;
rcv_pkt->length = buff_size;
memcpy(rcv_pkt->body, data_buffer, buff_size);
size = sizeof(rcv_pkt->magic) + sizeof(rcv_pkt->code) + sizeof(rcv_pkt->length) + buff_size;
if (send(ClientSocket, (char *)rcv_pkt, size, 0) == SOCKET_ERROR)
{
printf("Error %d\n", WSAGetLastError());
closesocket(ClientSocket);
//WSACleanup();
//return 1;
}
free(rcv_pkt);
break;
case CLICK_MOUSE:
coordX = pkt->Coords.x;
coordY = pkt->Coords.y;
//wsprintf(message, L"x:%d y:%d", coordX, coordY);
//MessageBox(NULL, message, NULL, MB_OK);
MoveMouse(coordX, coordY);
ClickMouse();
break;
default:
break;
}
/*
char send_buff[1024+1] = "";
ZeroMemory(&send_buff, 1025);
memset(send_buff, 'A', 1024);
recv_packet *rcv_pkt = (recv_packet *)malloc(sizeof(recv_packet)+1024+1);
//recv_packet rcv_pkt = { 0 };
rcv_pkt->magic = MAGIC;
rcv_pkt->code = 0;
rcv_pkt->length = strlen(send_buff)+1;
memcpy(rcv_pkt->body, send_buff, 1025);
int size = sizeof(rcv_pkt->magic) + sizeof(rcv_pkt->code) + sizeof(rcv_pkt->length) + 1024 + 1;
//printf("%d", size);
//getchar();
//return 0;
*/
}
} while (iResult > 0);
我将不胜感激任何帮助!谢谢。
答案 0 :(得分:1)
您一次只能阅读一条消息。如果套接字中有2条消息可用,则当前代码将同时读取这两条消息,但仅处理第一条消息。
将您的阅读更改为:
iResult = recv(ClientSocket, buff + numRcvBytes, sizeof(send_packet) - numRcvBytes, 0);
更好的方法是将接收提取到一个单独的功能:
int recvBytes(int socket, size_t numBytes, void *buffer) {
int numRcvBytes = 0;
while (numRcvBytes < numBytes)
{
iResult = recv(socket, buff + numRcvBytes, numBytes - numRcvBytes, 0);
if (iResult == SOCKET_ERROR)
{
// Leave cleanup to caller
return SOCKET_ERROR;
}
numRcvBytes += iResult;
}
return numRcvBytes;
}