2012-02-28 124 views
0

所以我尝试与客户端之间server.I发送结构两侧形成的结构:在server.c发生的memcpy()修改客户端套接字文件描述符

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

问题。我已经找到问题在这一行:

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修改插座的文件描述符..

+0

请确保您已完全复制导致出现问题的代码,以便在某人的答案显示代码中存在错误时不必编辑该问题。这对每个人都很困难。 – 2012-02-28 02:02:27

+1

什么是's1';什么是'sizeof(s1)'?在它的表面上,sizeof(s1)> sizeof(buffer_input)'因此你的'memcpy()'是践踏的边界,它所践踏的其中一个位恰好是你的文件描述符。添加一些断言 - 'assert(sizeof(s1)<= sizeof(buffer_input));'。然后在火灾发生时修理。此外,来自'perror()'的消息出现在'stderr'上,而不是'stdout',尽管差异很难发现。而且,如果断言没有触发,那么你的'省略了各种初始化'的代码可能会造成麻烦。随时随地打印客户端软件。 – 2012-02-28 02:07:34

回答

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

我编辑了我的post.it是一些打字错误我did.send()在这种情况下是正确的 – jasonkim 2012-02-28 01:58:14

+0

以及更多,我不知道如果send()支持发送一个结构作为它发送缓冲流的方式 – jasonkim 2012-02-28 01:59:24

+1

@ y26jin - 你可以用这种方式发送结构,因为它不包含指针。唯一的问题可能是两台机器的终结,但为了简洁起见,并且由于OP使用了'memcpy',我认为这两台机器是相同的端点。发送只需要一系列字节到xmit。 – 2012-02-28 02:12:38

2

memcpy不应,任何的情况下,修改文件描述符。

它所可能做的是覆盖内存,如果你给它不正确的参数,这似乎不太可能,因为我们有信息(s1应在300字节,比你允许buffer 1000少得多)。

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

我可以建议的只是调试代码。

您需要,调用memcpy,输出以下值前

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

然后在呼叫后再次输出它们。基于此,我们应该能够通过memcpy呼叫检测(或处置)腐败的可能性。

相关问题