memcpy () модифицированный дескриптор файла сокета клиента - PullRequest
0 голосов
/ 28 февраля 2012

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

 struct msg {
    char name[50];
    char time[50];
    int len;
    char buf[200];
 }

Проблема возникает в server.c. Я уже нашел проблему в этой строке:

 struct msg s1;
 char buffer_input[1024]={0};// the buffer stream for sending 
 ...// omitted all sorts of initializations cuz they all passed my debug and tests
 memset(buffer_input,0,sizeof(buffer_input));
 memcpy(buffer_input,&s1,sizeof(s1));
 /* Originally, the send() call read: */
 /* ssize_t size=send(client_sock,(struct sockaddr*)&client_sock_address,&addrlen); */
 ssize_t size=send(client_sock,buffer_input,sizeof(buffer_input),0);
 if(size<0) perror("send()");

тогда в стандартном выводе у меня есть:

send() : Socket operations on non-socket object

так что я догадываюсь, что причиной может быть memcpy(buffer_input,&s1,sizeof(s1)). Поэтому я изменил код как:

 memset(buffer_input,0,sizeof(buffer_input));
 strcpy(buffer_input,"example");

Функция send () работала отлично, и я получал сообщения в правильных форматах.

После серии отладок я понял, что после memcpy(...) файловый дескриптор клиентского сокета из 8 превратился в 0.

Так что мне интересно, в каких случаях memcpy может изменить файловый дескриптор сокетов ..

Ответы [ 2 ]

2 голосов
/ 28 февраля 2012

memcpy не должен, при любых обстоятельствах, изменять файловые дескрипторы.

Что может сделать , так это перезаписать память, если вы укажете ей неверные параметры, что маловероятно, учитывая имеющуюся у нас информацию (s1 должно составлять около 300 байт, что намного меньше, чем 1000, которое вы допускаете buffer).

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

Все, что я могу предложить, это отладочный код.

Вам необходимо, до вызова memcpy, вывести следующие значения:

  • sizeof(buffer).
  • &buffer.
  • sizeof (s1).
  • &s1.
  • client_sock.
  • &client_sock.

Затем выведите их снова после вызова. Исходя из этого, мы должны быть в состоянии обнаружить (или устранить возможность) коррупции с помощью вызова memcpy.

1 голос
/ 28 февраля 2012

Если строка

ssize_t size=send(client_sock,(struct sockaddr*)&client_sock_address,&addrlen); 

прочитана

ssize_t size=send(client_sock, buffer_input, 1024);

Или просто избавиться от buffer_input и иметь

ssize_t size=send(client_sock, &s1, sizeof(s1));

(вы также можете удалитьтакже и memset!)

РЕДАКТИРОВАТЬ

Еще немного кофе, вот лучшее решение:

/* 50 + 100 + 100 + 4 */
#define BUFFER_LENGTH 254

...

unsigned char buffer[BUFFER_LENGTH];

...

memcpy(buffer, s1.name, 50);
memcpy(buffer + 50, s1.time, 50);
uint32_t net_len = htonl(s1.len);
memcpy(buffer + 100, &net_len, 4);
memcpy(buffer + 104, ss1.buf, 100);

...

ssize_t size=send(client_sock, buffer, BUFFER_LEN);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...