我在C中编写服务器 - 客户端程序。客户端以5个字节的形式向服务器发送命令:第一个字节是操作,接下来的4个字节是执行操作的关键。操作。
服务器看起来像这样:
int nowread, key;
while(1)
{
char buffer[1024];
int alreadyread = 0;
do
{
nowread = read(socket,buffer+alreadyread,5-alreadyread);
alreadyread += nowread;
}
while((nowread > 0) && (5-alreadyread > 0));
if(nowread == -1 || nowread == 0)
{
printf("Error reading from client socket\n");
exit(1);
}
key = (((int)buffer[1])<<24 | ((int)buffer[2])<< 16 | ((int)buffer[3]) << 8 | ((int)buffer[4]) << 0);
printf("%d, key from server \n",key); // just for debugging
//DO COMMAND
我通过让客户端发送10个命令来测试程序:
op: 1, num: 645110
op: 2, num: 419811
op: 0, num: 115300
op: 2, num: 792023
op: 2, num: 146624
op: 1, num: 842346
op: 1, num: 450778
op: 0, num: 550046
op: 1, num: 284186
op: 2, num: 691858
我从服务器上来了:
-10, key from server
-29, key from server
-15772, key from server
-41, key from server
-64, key from server
-9622, key from server
-38, key from server
-98, key from server
284186, key from server
-110, key from server
正如您所看到的,只有一个键匹配,这很奇怪(要么它们都匹配,要么都不匹配)。我100%确定这是服务器端,而不是客户端的问题。有谁知道这可能导致什么?
提前致谢。
编辑: 这是发送数据的代码
uint32_t net_num = htonl(num);
int nsent = 0;
while (nsent < 4)
{
rc = write(sockfd,&net_num + nsent, 4 - nsent);
if (rc <= 0)
{
printf("error! write() failed: %s\n", strerror(errno));
break;
}
nsent += rc;
}
if (rc <= 0)
break;
答案 0 :(得分:1)
char
类型在您的系统上签名,因此当您在计算服务器端的int
值时将字节值转换为key
时,会对字节值进行符号扩展。不需要显式的强制转换,没有它们的结果是相同的。
您必须将buffer
数组unsigned char
:
unsigned char buffer[1024];
客户端代码也是错误的,仅当nsent
为0
时才有效。如果出于某种不可能的原因write
仅在1
和3
字节之间写入,您将尝试从net_num
变量的末尾之外的内存中传输字节,从而调用未定义的行为:
写(sockfd,&amp; net_num + nsent,4 - nsent);
你应该这样做:
write(sockfd, (unsigned char*)&net_num + nsent, 4 - nsent);
或者更好,为了与服务器代码保持一致:
char buffer[5];
ssize_t rc, nsent;
buffer[0] = code;
buffer[1] = (num >> 24) & 255;
buffer[2] = (num >> 16) & 255;
buffer[3] = (num >> 8) & 255;
buffer[4] = (num >> 0) & 255;
for (nsent = 0; nsent < 5; nsent += rc) {
rc = write(sockfd, buffer + nsent, 5 - nsent);
if (rc <= 0) {
printf("error! write() failed: %s\n", strerror(errno));
break;
}
}
if (rc <= 0)
break;
答案 1 :(得分:1)
您正在以错误的方向处理缓冲区。您还需要从网络字节转换回来。 ntohl()就是这么做的。
像这样:
strcmp()