memcpy()修改了客户端套接字文件描述符

时间:2012-02-28 01:51:27

标签: c sockets

所以我试图在客户端和服务器之间发送一个结构。我在两边定义了一个结构:

 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(...)之后,客户端套接字的文件描述符从0变为8

所以我想知道,在什么情况下memcpy可以修改套接字的文件描述符..

2 个答案:

答案 0 :(得分:2)

任何情况下,

memcpy不应修改文件描述符。

所做的事情就是覆盖内存,如果你给它不正确的参数,这似乎不太可能,因为我们拥有的信息(s1应该是大约300字节,远小于1000你允许buffer)。

你的缓冲区对你的结构来说太小的可能性似乎很低,如果那个代码确实是你所拥有的(无论是在文本和顺序方面,包括不进入或退出函数)。

我所能建议的只是调试代码。

您需要在调用memcpy之前输出以下值:

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

然后在通话后再次输出。基于此,我们应该能够通过memcpy调用来检测(或处理)腐败的可能性。

答案 1 :(得分:1)

该行

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