当前位置:  开发笔记 > 程序员 > 正文

套接字如何在C中工作?

如何解决《套接字如何在C中工作?》经验,为你挑选了2个好方法。

我对C中的套接字编程有点困惑.

您创建一个套接字,将其绑定到一个接口和一个IP地址,然后让它听.我发现了几个网络资源,并且理解得很好.特别是,我发现一篇文章在Unix系统下的网络编程非常有用.

令我困惑的是数据到达套接字的时间.

你怎么知道数据包何时到达,数据包有多大,你自己必须做所有繁重的工作吗?

我的基本假设是数据包可以是可变长度的,所以一旦二进制数据开始出现在套接字中,你如何从那开始构造数据包呢?



1> dfjacobs..:

简短的回答是你必须自己完成所有繁重的工作.可以通知您有可读取的数据,但您不知道有多少字节可用.在大多数使用可变长度数据包的IP协议中,将有一个标头,其前面包含已知的固定长度.此标头将包含数据包的长度.您读取标头,获取数据包的长度,然后读取数据包.重复此模式(读取标头,然后读取数据包),直到通信完成.

从套接字读取数据时,请求一定数量的字节.读取调用可能会阻塞,直到读取所请求的字节数,但它可以返回的字节数少于请求的字节数.发生这种情况时,您只需重试读取,请求剩余的字节.

这是一个典型的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;
}



2> 小智..:

因此,您的问题的答案取决于您是否使用UDP或TCP作为传输.

对于UDP,生活变得更加简单,因为您可以使用所需的数据包大小调用recv/recvfrom/recvmsg(您可能无论如何都要从源发送固定长度的数据包),并假设数据可用,它是数据包长度的倍数.(IE你用你的发送端数据包的大小调用recv*,你已经设置好了.)

对于TCP,生活变得更有趣 - 为了解释的目的,我将假设您已经知道如何使用socket(),bind(),listen()和accept() - 后者就是你如何获得新建连接的文件描述符(FD).

有两种方法可以为套接字执行I/O - 阻塞,在其中调用read(fd,buf,N)并且读取位于那里并等待直到您将N个字节读入buf - 或非阻塞,你必须检查(使用select()或poll())FD是否可读,然后你的read().

在处理基于TCP的连接时,操作系统不会关注数据包大小,因为它被认为是连续的数据流,而不是单独的数据包大小的块.

如果您的应用程序使用"数据包"(您传递的打包或解包数据结构),您应该能够使用正确的大小参数调用read(),并一次从套接字读取整个数据结构.您必须处理的唯一警告是,在源和目标系统具有不同字节字节的情况下,记住要正确地对您发送的任何数据进行字节顺序排序.这适用于UDP和TCP.

就*NIX套接字编程而言,我强烈推荐W. Richard Stevens的"Unix网络编程,第1卷"(UNPv1)和"Unix环境中的高级编程"(APUE).第一个是关于基于网络的编程的一本书,无论传输如何,后者是一个很好的全面编程书,因为它适用于基于*NIX的编程.另外,查看"TCP/IP Illustrated",第1卷和第2卷.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有