我在客户端 - 服务器程序的服务器端接收正确的值时遇到问题。
服务器和客户端中包含的头文件:
#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
可能是什么问题?我知道它不是那么容易,服务器 - 客户端通信是以字节流而不是消息进行的,但我想通过确认每个收到的消息来模仿该功能&#34;。你能告诉我该怎么办?我变得绝望了。
答案 0 :(得分:1)
您不会显示建立连接的代码。
如果您使用的是UDP套接字,则每条消息都是独立的,您将收到针对发送的每条消息的单独消息,但不一定按照相同的顺序。
如果您使用的是TCP或Unix套接字,则可能会以不同于发送方式的块大小接收数据。仅保留字节序列,而不保留块大小。您需要指定一个协议:除非您为每条消息指定固定数量的字节,否则您需要发送某种分隔符以允许服务器告知每条消息的结束位置。
答案 1 :(得分:1)
您需要一个协议。 例如,您定义应用程序中的每条消息都具有以下格式:
xx | message
这意味着您收到的前两个字节(记住字节顺序)表示后面的消息长度。现在你应该首先接收前两个字节 - 检查长度 - 然后确切地接收该字节数。之后,您知道您已成功收到该消息。然后你可以继续其他消息(可能/应该有类似的格式:长度+消息本身)。
实施例: 假设您要发送三条消息:
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
(因为发送和接收可能不会发送/接收您告诉它的字节数) :
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
功能。