未在服务器端客户端-服务器 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) 而不是 send
和 receive
(因为发送和接收可能 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
功能。
我在客户端-服务器程序的服务器端接收正确值时遇到问题。
服务器端和客户端都包含的头文件:
#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) 而不是 send
和 receive
(因为发送和接收可能 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
功能。