如何用 C 语言将任意大的文件读取到 TCP 套接字?

发布于 2025-01-03 12:06:45 字数 1860 浏览 0 评论 0原文

我刚刚学习套接字编程,我正在尝试编写一个回显客户端,该客户端从标准输入读取并写入套接字,然后从套接字读取服务器响应到标准输出。问题是我不知道标准输入有多长,也不知道服务器的响应有多长。我尝试使用的代码如下(创建套接字并连接到服务器被省略):

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。当我运行我的程序时,程序通常会连接到服务器并发送正确的消息,但是什么它写入标准输出要么什么都没有,要么是乱码。

我做错了什么?

I am just learning socket programming and I am trying to write an echo client that reads from stdin and writes to a socket and then reads the server response from the socket to stdout. The problem is that I don't know how long stdin will be or how long the server's response will be. The code I am trying to use is as follows (creating the socket and connecting to the server are left out):

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 is defined as 100. When I run my program the program typically connects to the server and sends the proper message, but what it writes to stdout is either nothing or gibberish.

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别忘他 2025-01-10 12:06:45

你的 while 循环只会在第一次运行。 read()/write() 只会返回它们实际读/写的数量,这很可能不等于 BUF_SIZE。假设您从套接字读取了 10 个字节,然后向 stdout 写入了 100 个字节 - 最后 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;
    }
}

Your while loop is only going to work the first time through. read()/write() are only going to return the amount that they actually read/write which may well not be equal to BUF_SIZE. Let's say you read ten bytes from the socket and then you write a hundred to stdout - the last 90 are going to be garbage.

Something along these lines will get you somewhat closer to what you want.

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文