0

会安装 valgrind 来告诉我问题出在哪里,但不幸的是这台计算机上不能有任何新程序......谁能告诉我这个“回声”程序是否存在明显问题?为朋友这样做,所以不确定客户端的布局是什么,但我知道读取和写入都是有效的套接字描述符,并且我已经测试了 n = write(writes,"I got your消息\n",20); 和 n = write(reads,"I got your message \n",20); 两者都有效,因此可以确认这不是无效 fd 的情况。谢谢!

int
main( int argc, char** argv ) {


 int reads = atoi(argv[1]) ; 
 int writes = atoi(argv[3]) ; 
 int n ; 


  char buffer[MAX_LINE];
  memset(buffer, 0, sizeof(buffer));



  int i = 0 ; 
  while (1) {
    read(reads, buffer, sizeof(buffer));
    n = write(writes,buffer,sizeof(buffer));
    if (n < 0)  perror("ERROR reading from socket"); 

  } 
4

4 回答 4

1

到目前为止还没有说明的一点:尽管您知道文件描述符是有效的,但您应该对命令行进行一些完整性检查。

if (argc < 3) {
       printf("usage: foo: input output\n");
       exit(0);
}

即使在命令行上进行这种健全的检查传递参数也是很危险的。

于 2012-07-24T18:00:10.693 回答
1

这两行看起来很可疑:

int reads = atoi(argv[1]) ; 
int writes = atoi(argv[3]) ; 

您真的在命令行上获得文件/套接字描述符编号吗?从哪里?

检查 and 的返回值read(2)write(2)然后检查errno(3)- 他们可能会告诉您文件描述符无效(EBADF)的值。

于 2012-07-24T15:09:36.230 回答
1

有一些问题,其中最紧迫的是您可能会在写入时使用 sizeof(buffer) 将垃圾数据向下推到写入套接字。假设您从读取套接字读取数据并且它小于 MAX_LINES。当您去写入该数据时,您将写入您读取的任何内容以及缓冲区末尾的垃圾(即使您在一开始就 memset,连续使用相同的缓冲区而不对不同的读取大小做出反应可能会产生一些垃圾。

尝试从读取中获取返回值并在您的写入中使用它。如果读取返回指示错误,请清理并退出或重试,具体取决于您希望程序的行为方式。

int n, size;
while (1) {
   size = read(reads, buffer, sizeof(buffer));

   if (size > 0) {
       n = write(writes, buffer, size);

       if (n != size) {
           // write error, do something
       }  
   } else {
       // Read error, do something
   }
}

当然,这假设您的写入和读取是有效的文件描述符。

于 2012-07-24T15:00:15.230 回答
0
  1. memset()不需要,只要您更改以下内容(尽管如此,您应该这样做)。
  2. read()有一个结果,告诉你它实际读了多少。你应该这样做write(),以便只写你实际拥有的东西,消除归零的需要。
  3. MAX_LINE至少应该是 512,如果不是更多的话。

可能还有更多问题,但我认为我有最重要的问题。

于 2012-07-24T14:39:21.680 回答