0

我在用 C 语言进行客户端服务器编程时遇到问题。

问题是代码卡在客户端代码中的 while 循环中。代码是@客户端:

while ((n_read=((read(sockfd,&buffer,sizeof(buffer))))>0)
{   
    buffer[n_read]='\0';                            
    write(fd,buffer,strlen(buffer));
    printf("------- the value of n_read is : %d\n",n_read)  ;
}

因此,当我在客户端使用 strace 调试此代码时,这里是系统调用的快照。我看到从服务器读取整个文件后n_read的值为1,但服务器在read=0后退出正常读取???我怎么解决这个问题

客户端代码的快照:

read(3, "._guardAgainstUnicode(pad)\n# Pad"..., 1025) = 1025
write(4, ".", 1)                        = 1
write(1, "------- the value of n_read is :"..., 35------- the value of n_read is : 1
) = 35
read(3, "crypted\nwith the already specifi"..., 1025) = 1025
write(4, "c", 1)                        = 1
write(1, "------- the value of n_read is :"..., 35------- the value of n_read is : 1
) = 35
read(3, " = bytes.fromhex('').join(result"..., 1025) = 1025
write(4, " ", 1)                        = 1
write(1, "------- the value of n_read is :"..., 35------- the value of n_read is : 1
) = 35
4

1 回答 1

2

代码正在缓冲区外写入​​。

如果读取的字节数填满缓冲区,n_read则等于 sizeof(buffer). 然后buffer[n_read]='\0'会写过去的结尾buffer

while ((n_read=((read(sockfd,&buffer,sizeof(buffer))))>0) 
{   
    buffer[n_read]='\0';   

而是用于n_read确定write()长度。

ssize_t n_read;
char buffer[1024];
while ((n_read = read(sockfd, buffer, sizeof buffer)) > 0) {    
  // buffer[n_read]='\0';                            
  // write(fd,buffer,strlen(buffer));
  write(fd, buffer, n_read);
  printf("------- the value of n_read is : %zu\n", (size_t) n_read)  ;
}

[编辑] OP 说“同样的问题卡住了”

在没有看到服务器代码的情况下,我提供的答案是......

服务器端不发送任何形式的“文件结尾”。服务器简单地停止发送数据。接收端不“知道”没有更多数据,它只是“知道”当时没有更多数据可用,因此耐心等待。

(按优先顺序)

1)确保服务器确实如此close(),这应该导致read()最终返回 < 0(参见@nos 评论)。

2)让服务器在最后一个时发送一个特殊字符。ASCII 代码 26 (^Z) 和 255(截断的典型 EOF)是典型的候选。然后,当接收者收到这样的内容时,它就会停止。

3) 形成数据包。服务器在发送的数据前面加上一个长度。客户端使用这个长度。负值可用于指示错误或 EOF。

于 2013-10-23T19:50:55.130 回答