Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C套接字:write()后跟close()会导致数据传输不完整_C_Sockets_Tcp_Network Programming_File Descriptor - Fatal编程技术网

C套接字:write()后跟close()会导致数据传输不完整

C套接字:write()后跟close()会导致数据传输不完整,c,sockets,tcp,network-programming,file-descriptor,C,Sockets,Tcp,Network Programming,File Descriptor,我试图编写一个基本的文件服务器,它从客户机获取文件名,并通过TCP将数据发送到客户机进行响应。我有一个工作客户机和服务器应用程序的大部分,但我观察一些奇怪的行为,考虑以下 while ((num_read = read (file_fd, file_buffer, sizeof (file_buffer))) > 0) { if (num_read != write (conn_fd, article_buffer, num_read)) {

我试图编写一个基本的文件服务器,它从客户机获取文件名,并通过TCP将数据发送到客户机进行响应。我有一个工作客户机和服务器应用程序的大部分,但我观察一些奇怪的行为,考虑以下

    while ((num_read = read (file_fd, file_buffer, sizeof (file_buffer))) > 0)
    {
        if (num_read != write (conn_fd, article_buffer, num_read))
        {
            perror ("write");
            goto out;
        }
    }
    out:
           close(file_fd); close(sub_fd);
file\u fd
是通过网络发送的文件的文件描述符,
conn\u fd
connect()
ed
TCP
套接字的文件描述符

这似乎适用于小文件,但当我的文件变大(兆字节+)时,文件末尾的一些不一致的数据量将无法传输

我怀疑写后立即关闭()语句可能与此有关,因此在两个
close()
语句之前,我尝试了1秒的
sleep()
,我的客户机成功地接收到了所有数据

有没有比在服务器端执行
sleep()
更好的方法来处理此问题?

套接字上的成功“写入”并不意味着数据已成功发送到对等方

如果您使用的是unix衍生工具,则可以执行“man 7 socket”并检查“SO_LINGER”作为潜在的解决方案

编辑:由于EJP的评论(谢谢),我重新阅读了Stevens在“Unix网络编程”中关于确保向对等方交付所有数据的主题所说的内容。他说了以下内容(在第二版第1卷,第189页):

…我们看到,根据调用的函数(close或shutdown)以及是否设置了SO_LINGER套接字选项,当我们关闭连接端时,返回可能在三个不同的时间发生

  • close立即返回,无需等待(默认值;图7.6)
  • close(关闭)将持续,直到收到我们的FIN确认(图7.7),或
  • 关闭,然后读取等待,直到我们收到对等方的FIN(图7.8)
  • 他的数字和注释表明,除了“应用程序级确认”之外,
    shutdown()
    ,然后是等待零返回代码的
    read()
    (即套接字已关闭的通知),这是确保客户端应用程序已收到数据的唯一方法


    但是,如果数据已经成功地传递(并确认)到对等方的计算机上才是重要的,那么再多停留就足够了。

    您在这里演示过客户端代码或服务器代码吗?fsync(2)?我尝试过fsync()它没有解决问题。我认为您还有其他一些问题。TCP套接字不会像这样丢弃数据,除非网络关闭。您应该检查
    read()
    close()的返回值(-1,尤其是它的
    errno
    也是。不仅在这种情况下,而且在一般情况下。因此,LINGER并不能真正解决这个问题,它只是能够检测何时无法写入最终挂起的数据。在这种情况下,问题几乎肯定在接收端。