未在服务器端客户端-服务器 TCP 上接收单独的值

Not receiving separate values on the server-side client-server TCP

我在客户端-服务器程序的服务器端接收正确值时遇到问题。

服务器端和客户端都包含的头文件:

#define CHUNK_SIZE 1024
#define ARR_LEN 3

客户:

int uids[ARR_LEN] = {1994, 2423, 1222};
unsigned int uidlen = 0;
char uidbuffer[CHUNK_SIZE] = {0};

for(int i = 0; i < ARLL; i++)
{
    uidlen = strlen(uids[i])+1;
    snprintf(uidbuffer, uidlen, "%s", uids[i]);

    if(send(socket, uidbuffer, strlen(uidbuffer), 0) < 0)
        DIE("Write Error");
    if(recv(socket, uidbuffer, sizeof(uidbuffer), 0) < 0)
        DIE("Acknowledge Error");

    memset(uidbuffer, 0, sizeof(uidbuffer));
}

服务器:

char uid_buff[CHUNK_SIZE];
for(int i = 0; i < ARR_LEN; i++)
{
    memset(uid_buff, 0, sizeof(uid_buff));
    // receiving the UID and storing it directly
    if(recv(client_sock, uid_buff, sizeof(uid_buff), 0) < 0)
        DIE("Receive Error");

    printf("buffer content: %s\n", uid_buff);
    uid_str = uid_buff;

    uids[i] = (uid_t)strtol(uid_str, (char **)NULL, 10);

    if(send(client_sock, uid_buff, sizeof(uid_buff), 0) < 0)
        DIE("Acknowledge Error");
}

这些只是我程序的一部分。我试图只包括相关部分。输出是这样的:

buffer content: 1994
buffer content: 24231222
buffer content: 

虽然我希望它是:

buffer content: 1994
buffer content: 2423
buffer content: 1222

可能是什么问题?我知道这不是那么容易,而且服务器-客户端通信是在字节流而不是消息中执行的,但我想通过确认每个接收到的消息来模拟该功能 "message"。你能告诉我该怎么做吗?我越来越绝望了。

您没有显示建立连接的代码。

如果您使用的是 UDP 套接字,则每条消息都是独立的,对于每条发送的消息,您都会收到一条单独的消息,但不一定按相同的顺序。

如果您使用的是 TCP 或 Unix 套接字,则接收到的数据块的大小可能与用于发送的数据块大小不同。仅保留字节序列,不保留块大小。您需要指定一个协议:除非您指定每条消息的固定字节数,否则您需要发送某种分隔符以允许服务器告知每条消息的结束位置。

你需要一个协议。 例如,您定义应用程序中的每条消息都具有以下格式:

xx | message

这意味着您收到的前两个字节(注意字节序)表示后面消息的长度。现在您应该首先接收前两个字节 - 检查长度 - 然后接收准确的字节数。之后您就知道您已成功收到该消息。然后你可以继续处理其他消息(could/should 具有类似的格式:长度 + 消息本身)。

示例: 假设您要发送三个消息:

char s1[]="message1";
char s2[]="message2";
char s3[]="message3";

//You do this(client side):

int x1 = strlen(s1); // length of message1
int intsize = 4; // just size of integer -we'll need in next call

sendall(socket, &x1, &intsize); // send length of first message
sendall(socket, s1, &x1); // Now send the message

//On server:
int x = 0;
int y = 4; //size of integer most probably
receiveall(socket,&x,&y);//get length first; y=4 because that is size of integer
receiveall(socket, buffer, &x); // now we know how many bytes to expect - x - so request that number of bytes only

您也可以对其他消息重复此逻辑。

最后,您想使用这样的函数 (here) 而不是 sendreceive(因为发送和接收可能 send/receive 您的字节数告诉它):

int sendall(int s, char *buf, int *len)
{
    int total = 0;        // how many bytes we've sent
    int bytesleft = *len; // how many we have left to send
    int n;

    while(total < *len) {
        n = send(s, buf+total, bytesleft, 0);
        if (n == -1) { break; }
        total += n;
        bytesleft -= n;
    }

    *len = total; // return number actually sent here

    return n==-1?-1:0; // return -1 on failure, 0 on success
} 

您将需要类似的 receiveall 功能。