2015-09-03 4 views
1

Я работал над небольшим чистым клиентским приложением C (мой первый: /), который использует TCP-сокет для связи с сервером. Сервер отправляет мне пакет (структура C), в котором первый байт содержит размер пакета.Использование unsigned char вместо char из-за его диапазона

Проблема заключается в том, что сервер использует unsigned char для представления размера пакета, поскольку char подписан (от -128 до +127) и +127 недостаточно для представления размера, который может быть до 255 в некоторых пакетах , => Мне нужен unsigned char buffer;

В Linux второй параметр функции recv() является void *, что означает, что я могу объявить буфер void *, и проблем нет. Но recv() в Windows (MinGW) имеет char * вместо void *. Который дает мне предупреждение «Несоответствие типа параметра: Несовместимые типы указателей« char * »и« unsigned char * »«

Можно ли решить эту проблему? Вот код. Благодарю.

PS: Я использую разъемы NON BLOCKING.

int recvsize = 0; 
unsigned char tmpsize; 
int index = 0; 
unsigned char *buffer; 

while (1) { 

    recvsize = recv(server, &tmpsize, sizeof(unsigned char), 0); // every packet starts with one byte where is its length 

    if (recvsize > 0) { 
     buffer = malloc(tmpsize * sizeof(unsigned char)); //memory allocation according to the size of packet 
     buffer[0] = tmpsize--; //get back the size value to the buffer 
     recvsize = 0; 


     do { //loop over and over until you do not have all bytes of the packet 
      recvsize = recv(server, &buffer[++index], tmpsize, 0); 

      if (recvsize == 0) 
       break; 


      tmpsize -=recvsize; 
      index += recvsize; 

     } while (tmpsize != 0); 

    } 
sleep(50); 
} 
+1

'char' может быть подписан на вашей платформе. Стандарт оставляет это для реализации. В общем, при передаче данных между различными системами (и чаще всего в одной и той же системе) предпочтительными являются типы 'stdint.h' и правильная сериализация. В противном случае ждет бродяга. – Olaf

+0

Примечание: 'sizeof (unsigned char)' всегда 1, поэтому '... * sizeof (unsigned char)' не требуется. Если код хочет отметить масштабирование по размеру переменной, предложите 'buffer = malloc (tmpsize * sizeof * buffer)' – chux

ответ

2

Просто наведите указатель на нужный тип. Так что используйте:

(char *) (&buffer[++index]) 

Кроме того, почему вы создаете схему блокировки, повторяя неблокируемую операцию в цикле сна? Либо используйте блокирующие сокеты, либо используйте неблокирующие сокеты, но не создавайте фальшивую промежуточную вещь. (Если, например, злонамеренный или медленный клиент отправляет вам только один байт, вы будете вращаться на recv.)

Наконец, почему вы читаете только один байт при первом вызове recv? В любом случае, вам понадобятся остальные данные, поэтому зачем ядро ​​отдавать его вам в крошечных каплях? Почему бы не прочитать столько байтов, сколько сможете, и, если повезет, во второй раз избежать необходимости звонить recv?

+0

Да, моя ошибка! – cdonts

+0

«Почему вы читаете только один байт при первом вызове? Хм, возможно, может быть несколько сообщений, и, читая« столько байтов, сколько сможете », может не кодировать получение нескольких или частичных сообщений, а затем им нужно управлять? – chux

+1

@chux Да, конечно. Это характер TCP. Прямо сейчас он заставляет ядро ​​делать это. Он уже обрабатывает частичные сообщения. –

Смежные вопросы