Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
memcpy()修改的客户端套接字文件描述符_C_Sockets - Fatal编程技术网

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

memcpy()修改的客户端套接字文件描述符,c,sockets,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 al

因此,我尝试在客户端和服务器之间发送一个结构。我在两侧定义了一个结构:

 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()");
所以我有一种预感,
memcpy(buffer\u input,&s1,sizeof(s1))
可能是原因。所以我修改了代码如下:

 memset(buffer_input,0,sizeof(buffer_input));
 strcpy(buffer_input,"example");
send()工作正常,我收到的消息格式正确

经过一系列调试,我意识到在
memcpy(…)
之后,客户端套接字的文件描述符从
8
变为
0

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

是否应该删除该行

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

或者干脆去掉
buffer\u输入
,然后

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);
应该排队吗

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

或者干脆去掉
buffer\u输入
,然后

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

memcpy
在任何情况下都不应修改文件描述符

如果您给内存提供了不正确的参数,它可能会覆盖内存,考虑到我们拥有的信息,这似乎不太可能(
s1
应该是300字节左右,远小于
缓冲区允许的1000字节)

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

我只能建议调试代码

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

  • sizeof(缓冲区)
  • &缓冲区
  • sizeof(s1)
  • &s1
  • client\u sock
  • &客户端\u sock

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

memcpy
在任何情况下都不应修改文件描述符

如果您给内存提供了不正确的参数,它可能会覆盖内存,考虑到我们拥有的信息,这似乎不太可能(
s1
应该是300字节左右,远小于
缓冲区允许的1000字节)

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

我只能建议调试代码

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

  • sizeof(缓冲区)
  • &缓冲区
  • sizeof(s1)
  • &s1
  • client\u sock
  • &客户端\u sock

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

我编辑了我的帖子。这是我做的一些键入错误。send()在这种情况下是正确的,而且,我不知道send()是否正确支持以发送缓冲区的方式发送结构stream@y26jin-您可以通过这种方式发送结构,因为它不包含指针。唯一的问题可能是这两台机器的长度,但为了简洁起见,正如OP使用的
memcpy
一样,我假设这两台机器的长度相同。send只需要一系列字节就可以发送到xmit。@Ed endian ness不是唯一的问题。。。这两台机器也可能有不同的结构填充规则,或不同的sizeof(int)值。以这种方式发送结构是不可移植的,除非发送和接收机器非常相似,并且编译后的代码两边都使用相同的设置进行编译,否则很可能会中断。@Jeremy-你说得对-最好将其序列化。那时没有足够的咖啡!我编辑了我的帖子。这是我犯的一些键入错误。send()在这种情况下是正确的,而且,我不知道send()是否支持以发送缓冲区的方式发送结构stream@y26jin-您可以通过这种方式发送结构,因为它不包含指针。唯一的问题可能是这两台机器的长度,但为了简洁起见,正如OP使用的
memcpy
一样,我假设这两台机器的长度相同。send只需要一系列字节就可以发送到xmit。@Ed endian ness不是唯一的问题。。。这两台机器也可能有不同的结构填充规则,或不同的sizeof(int)值。以这种方式发送结构是不可移植的,除非发送和接收机器非常相似,并且编译后的代码两边都使用相同的设置进行编译,否则很可能会中断。@Jeremy-你说得对-最好将其序列化。那时没有足够的咖啡!请确保您准确地复制了导致问题的代码,这样当有人的答案表明代码中有错误时,您就不必编辑问题。这对每个人来说都很困难。什么是
s1
;(s1)
的大小是多少?从表面上看,
sizeof(s1)>sizeof(buffer_input)
,因此您的
memcpy()
超出了范围,它所占用的位之一恰好是您的文件描述符。添加一些断言--
assert(sizeof(s1)请确保您准确地复制了导致问题的代码,这样当有人的回答表明代码中有错误时,您就不必编辑问题。这会给每个人带来困难。什么是
s1
;什么是
sizeof(s1)
?从表面上看,
sizeof(s1)>sizeof(buffer\u input)
,因此您的
memcpy()
被践踏了