我有点困惑socket programming in C。

你创建的一个插座,结合到一个接口和一个IP地址,并得到它听。我发现一对夫妇的网上资源,理解它的罚款。特别是,我发现了一篇文章 网络程序下的Unix系统 要内容非常丰富。

什么混淆了我的时机到达的数据在座。

怎么你可以告诉当包抵达,以及有多大的分组是,你必须做的所有重提升自己?

我的基本假设是,分组可以变长,所以一旦的二进制数据开始出现下插座,你怎么开始构建包?

有帮助吗?

解决方案

简短的回答是,你必须做的所有重提升自己。你可以通知有数据可供读取的,但是你不会知道多少字节。在大多数知识产权协议使用的变长的报文,将有一头与一个已知的固定长度的前面添加以分组。这个标题将包含长的分组。你读头,得到长的分组,然后读取数据包。你重复这一模式(阅读头,然后读取分组),直到通信是完整的。

阅读时的数据从一个插座,你要求一定数量的字节。读呼吁可能阻,直到所请求的数字节读,但它可以减少返回的字比请求。当发生这种情况,只需重新阅读,要求剩余的字节。

这是一个典型的C功能阅读一组数字从一个插座:

/* buffer points to memory block that is bigger than the number of bytes to be read */
/* socket is open socket that is connected to a sender */
/* bytesToRead is the number of bytes expected from the sender */
/* bytesRead is a pointer to a integer variable that will hold the number of bytes */
/*           actually received from the sender. */
/* The function returns either the number of bytes read, */
/*                             0 if the socket was closed by the sender, and */
/*                            -1 if an error occurred while reading from the socket */
int readBytes(int socket, char *buffer, int bytesToRead, int *bytesRead)
{
    *bytesRead = 0;
    while(*bytesRead < bytesToRead)
    {
        int ret = read(socket, buffer + *bytesRead, bytesToRead - *bytesRead);
        if(ret <= 0)
        {
           /* either connection was closed or an error occurred */
           return ret;
        }
        else
        {
           *bytesRead += ret;
        }
    }
    return *bytesRead;
}

其他提示

所以回答你的问题取决于一个公平一点上你是否是使用UDP或TCP作为你的运输。

UDP,生活变得简单得多,在那你可以打电话接收/recvfrom/recvmsg与包的尺寸您需要(你可能会发送的固定长度的数据包源无论如何),并使假设,如果数据是可用的,它的存在的倍数分组的长度大小。(E.I.你打电话接收*与大小,发送方分组,并就设置。)

TCP,生活变得有点更有趣的-为目的的这种解释,我会假设你已经知道如何使用socket(),bind(),listen()接受()-后者是如何获得的文件描述(FD)为你的新作出连接。

有两种方法的做I/O为一座阻挡,其中你打电话读(fd,buf,N)和读坐在那里等待直到你读N字节到buf或无阻,这对你有检查(利用选择()或投票())是否FD是可读的,然后做你的读().

在处理基于TCP连接,操作系统没注意到包的尺寸,因为它被认为是一个持续不断的流数据,没有单独的报大小的块。

如果应用程序使用的"分组"(包装或解压缩的数据结构你绕过),你应该可以打电话read()用适当的尺寸参数,并宣读一个完整的数据的结构断插座在一段时间。唯一需要注意的已处理的,是要记住,以适当字节顺序的任何数据,你发送的,在情况下的来源和目的地系统的不同endian byte-ness。这适用于UDP和TCP。

尽*NIX socket programming感到关切的是,我强烈建议WRichard Stevens'"Unix网络编,第一卷。1"(UNPv1)和"先进的节目在一个Unix环境"(APUE).第一是一个多关于网络为基础的方案拟订,而不论运输,而后者是一个良好的所有程书,因为它适用于*NIX基础的方案编制。此外,寻找"TCP/IP说明",卷1和2。

当你读的插座,你告诉它如何许多最大的字节阅读,但如果它没有很多,它给你然而,许多它的了。这是给你的设计的协议,所以你知道你是否已经得到了部分分组或没有。例如,在过去的时发变长的二进制数据,我会把一个int在一开始所说的有多少字节到期望。我愿意做一个读请求的字节数大于尽可能最大的分组在我的协议,然后我会比第一int对但是许多字节我会接收和处理或试图更多的读直到我得到完整的分组,同。

卯工作在一个高水平,比原分组-它就像一个文件中,你可以读写。此外,当试图阅读由一个插座,操作系统将阻止(暂时搁置)过程,直至它有数据,以满足该请求。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top