2015-06-13 1 views
-1

Я пытаюсь написать сервер-клиентскую программу на C, где клиент отправит кучу сообщений в виде 5 байтов: первый байт будет содержать команду , а следующие четыре будут содержать ключ. Это выглядит примерно так:Сервер-клиент в C: странное поведение при отправке байтов

rc = write(sockfd, &op, 1); 
    if (rc != 1) 
    { 
     printf("error! write() failed: %s\n", strerror(errno)); 
     break; 
    } 

    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; 
} 

На приемном конце, у меня есть:

while((bytes = recv(socket,buffer,5,0)) > 0) 
    { 
     //printf("%d\t%d\t%d\t%d\t%d\n",(int)buffer[0],(int)buffer[1],  (int)buffer[2],(int)buffer[3],(int)buffer[4]); 
     key = ((buffer[4] << 24) | (buffer[3] << 16) | (buffer[2] << 8) | (buffer[1])); 

     if((int)buffer[0] == 0) 
     { 

      do command 0, etc... 

Проблема у меня в том, что я не могу получить ключ. Я попытался переключить порядок сдвигов, но все, что я получаю, это числа, которые не соответствуют ключам, которые отправляет клиент. Я в недоумении.

Даже незнакомец, это то, что если я скомпилирую сервер без печати под временем, я получаю seg-fault. Если я раскомментирую printf, он отлично работает. Это кажется супер странным.

Кто-нибудь знает, что может быть причиной этого? Спасибо заранее.

+0

'& net_num + nsent,' неправильно использует указатель arithmatic на тип 32 бит. Перед добавлением сначала необходимо преобразовать в 8-разрядный тип указателя. – wildplasser

+0

WRONG: 'rc = write (sockfd, & net_num + nsent, 4 - nsent);'. ЛУЧШЕ: 'rc = write (sockfd, & net_num, sizeof (net_num));'. ТАКЖЕ: как вы выделили «буфер»? Достаточно ли это? Вы передаете правильный размер буфера? В этом случае почему бы вам просто не использовать «& net_num» и «ntohl()» в вашем «recv()»? – paulsm4

+0

Есть ли способ исправить эту серверную сторону? –

ответ

0

rc = write(sockfd, &net_num + nsent, 4 - nsent); не соответствует действительности, &net_num является указателем на 32-битный объект, поэтому &net_num+1 будет указывать на следующий объект 32 бит. Это выходит за рамки объекта. Вы можете приведённый к указателю полукокса, или скопировать в буфер небольшого полукокса перед отправкой, как показано ниже:


uint32_t net_num = htonl(num); 
char buff[sizeof net_num]; 
memcpy (buff, &net_num, sizeof buff); 

int nsent; 
for nsent=0; nsent < sizeof buff; nsent += rc;) 
{ 
    rc = write(sockfd, buff + nsent, 4 - nsent); 
    if (rc == -1 && errno == EAGAIN) { rc=0; continue; } 
    if (rc <= 0) 
    { 
     printf("error! write() failed: %s\n", strerror(errno)); 
     break; 
    } 


} 
+0

Спасибо за помощь, но, к сожалению, это не сработает. Я бросил указатель на символ и ничего не изменил. –

+0

Может быть больше ошибок. (Я читаю как корректор: я останавливаюсь, когда сталкиваюсь с первой ошибкой. Извините!) – wildplasser