2012-07-24 124 views
0

会安装valgrind告诉我问题是什么,但不幸的是不能在这台计算机上的任何新程序......任何人都可以告诉我,如果这个“回声”程序存在明显的问题?这样做是为了朋友,所以不知道客户端的布局是什么,但我知道读写都是有效的套接字描述符,并且我测试了n = write(写道,“我得到了你的消息\ n“,20);和n =写(读,“我收到了你的消息\ 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"); 

    } 
+0

在发生错误时检查read()结果。使用memset的 – 2012-07-24 14:42:13

回答

0
  1. memset()是不需要的,只要你更改以下(你应该做的不过)。
  2. read()有一个结果,告诉你它实际上读了多少。这个你应该给write(),以便只写出你实际拥有的东西,而不需要调零。
  3. MAX_LINE应该至少为512,如果不是更多。

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

+0

不会对成功与否产生任何影响。 max_line> 512时也是如此。无论哪种方式仍然不起作用:( – user1018513 2012-07-24 14:57:42

+0

你是对的,我的要点是2.,这可能会影响很多。顺便说一句:你还没有告诉我们什么是真正的问题... – glglgl 2012-07-24 15:01:37

+0

当我尝试时程序崩溃读书。 – user1018513 2012-07-24 15:23:32

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 
    } 
} 

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

1

帖e两行看起来非常可疑:

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

你真的在命令行上得到文件/套接字描述符号吗?来自哪里?

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

+0

没有我的文件描述符是肯定有效的(通过我可以执行n =写入(读取,“我得到了你的消息\ n”,20),并在另一边接收它 – user1018513 2012-07-24 15:12:18

+0

,如果我在随机值中读取,或写道然后我确实得到“无效的文件描述符”),但我的代码现在默默地失败 – user1018513 2012-07-24 15:15:02

+0

你是什么意思的“默默”? – 2012-07-24 15:16:10

1

到目前为止还没有提出的一点:虽然你知道文件描述符是有效的,但你应该包括一些对命令行的完整性检查。

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

即使有这种理智检查在命令行中传递这样的参数可能是危险的。