如何在C中将任意大的文件读取到TCP套接字?

时间:2012-02-07 05:14:16

标签: c sockets tcp client-server

我正在学习套接字编程,我正在尝试编写一个从stdin读取并写入套接字的echo客户端,然后从套接字读取服务器响应到stdout。问题是我不知道stdin将持续多长时间或服务器的响应时间。我试图使用的代码如下(创建套接字并连接到服务器被省略):

length = BUF_SIZE;
while (length == BUF_SIZE) {  // length will equal BUF_SIZE if buf is full, when length < BUF_SIZE we have reached an EOF                                 
   // Reads from STDIN to buf                                                                                                                              
   if ((length = read(STDIN_FILENO, buf, BUF_SIZE)) < 0){
     fprintf(stderr, "Error in reading from STDIN");
     return 4;
   }
   // Writes from buf to the socket                                                                                                                        
   if ((write(sock, buf, BUF_SIZE)) < 0){
     fprintf(stderr, "Error writing to socket");
     return 5;
   }
 }

if ((status = shutdown(sock, 1)) < 0){ // Shuts down socket from doing more receives                                                                      
   fprintf(stderr, "Error shutting down socket for writing");
   return 6;
}

length = BUF_SIZE; 
while (length == BUF_SIZE){
   // Read from socket to buf                                                                                                                              
   if ((length = read(sock, buf, BUF_SIZE)) < 0){
     fprintf(stderr, "Error reading from socket");
     return 7;
   }
   // Write from buf to STDOUT                                                                                                                             
   if ((write(STDOUT_FILENO, buf, BUF_SIZE)) < 0){
     fprintf(stderr, "Error writing to STDOUT");
     return 8;
   }
}

close(sock);
exit(0);

BUF_SIZE定义为100.当我运行程序时,程序通常会连接到服务器并发送正确的消息,但它写入stdout的内容是什么都没有或者是乱码。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

你的while循环只能在第一次工作。 read()/ write()只返回它们实际读/写的数量,这可能不等于BUF_SIZE。假设您从套接字中读取了10个字节,然后向stdout写了一百个 - 最后90个将是垃圾。

沿着这些方向的某些东西会让你更接近你想要的东西。

while (1)
{
    if ((length = read(STDIN_FILENO, buf, BUF_SIZE)) < 0)
    {
        fprintf(stderr, "Error in reading from STDIN");
        return 4;
    }

    if ((write(sock, buf, length)) < 0)
    {
        fprintf(stderr, "Error writing to socket");
        return 5;
    }

    if ((length = read(sock, buf, BUF_SIZE)) < 0)
    {
        fprintf(stderr, "Error reading from socket");
        return 7;
    }

    if ((write(STDOUT_FILENO, buf, length)) < 0)
    {
        fprintf(stderr, "Error writing to STDOUT");
        return 8;
    }
}