C:客户端和服务器之间的奇怪行为

时间:2015-06-14 16:59:22

标签: c ubuntu websocket server

我在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;

2 个答案:

答案 0 :(得分:1)

char类型在您的系统上签名,因此当您在计算服务器端的int值时将字节值转换为key时,会对字节值进行符号扩展。不需要显式的强制转换,没有它们的结果是相同的。

您必须将buffer数组unsigned char

unsigned char buffer[1024];

客户端代码也是错误的,仅当nsent0时才有效。如果出于某种不可能的原因write仅在13字节之间写入,您将尝试从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()