网络编程之基本通信函数

本文介绍了网络编程的基本概念,包括TCP和UDP连接的建立过程,并详细解释了socket编程中的关键函数,如socket(), bind(), listen(), accept(), connect(), read(), write(), recvfrom(), sendto()等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网络编程,也就是建立一个客户端和服务器间的一个socket连接。这篇文掌将介绍一些关于网络编程的函数。

 

一:TCP 连接示意图

 

 

二: UDP连接示意图

 

 

 

三、函数介绍

 1、创建一个socket套接字,返回一个文件描述符

      int socket(int domain, int type, int protocol)

      参数分析:

      domain: 协议族名,如AF_INET、AF_PACKET等。详情见文件/usr/include/linux/socket.h。

      type:  希望建立连接的类型,可以是tcp(SOCK_STREAM),也可以是udp(SOCK_DGRAM).

      protocol:表示该协议族中的那种协议,0表示自动选择。

2、绑定(绑定本地的一个ip和端口)

     int bind(int socket,  const struct sockaddr *address,  socklen_t address_len);

     参数分析:

     socket: socket()函数创建时,返回的一个文件描述符.

     address: 一个包含ip和端口的结构体。在通常情况下,使用结构体struct sockaddr_in结构体。赋值后,强制类型转换为struct sockaddr 类型。

     address_len: 第二个参数结构体的大小。

     结构体内容:

     struct sockaddr_in

    {
            sa_family_t       sin_family;                     /* Address family       */
            unsigned short int    sin_port;               /* Port number          */
            struct in_addr    sin_addr;                    /* Internet address     */
 
            /* Pad to size of `struct sockaddr'. */
            unsigned char     __pad[ __SOCK_SIZE__ - sizeof(short int) -
                                                     sizeof(unsigned short int) - sizeof(struct in_addr)];
     };

    struct in_addr

    {
         __u32   s_addr;
     };

    使用说明:

     struct sockaddr_in server;

     server.sin_family = AF_INET;

     server.sin_addr.s_addr = inet_addr('192.168.1.177');

     server.sin_port = htons(9734);

     bind(sockfd, (struct sockaddr *)&server, sizeof(server));

 

 3、设置监听客户端连接的个数

      int listen(int sockfd, int backlog);

      参数分析:

      sockfd: socket()函数返回的文件描述符;

      backlog: 设置监听的个数;

 

 4、等待客户端的握手连接, 返回一个用于双方通信的描述符。该函数和connect()对应。

      int accept(int socket, struct sockaddr *restrict_address, socklen_t * restrict_address_len);

      参数说明:

      socket:socket()函数返回的描述符。

      restrict_address: 用于存放connect()函数连接时传递过来的客户端struct sockaddr结构体,可以获取对方IP.

      restrict_len: 该结构体的大小,也就是sizeof(struct sockaddr);

5、客户端和服务器握手连接的函数

     int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

     参数分析:

     sockfd:  客户端socket()函数返回的一个socket描述符;

     serv_addr: 用于存放服务器的ip地址和端口号的结构体,和上面的bind()函数一样。

     addrlen:结构体的长度。

 6、适应于tcp连接的数据交互

 6.1、数据接收

        ssize_t read(int fildes, void *buf, size_t nbyte)

        files:在服务器端是accept()返回的描述符,在客户端表示socket()返回的描述符

        buf: 用于保存接受的数据。

        nbyte: 表示接受多少长度的字节数

 

       ssize_t recvmsg(int s, struct msghdr *msg, int flags)

       s:在服务器端是accept()返回的描述符,在客户端表示socket()返回的描述符。

       msg:用于存储发送过来的数据,还有数据长度,以及相关的信息。

       flags:接受数据的的标志通常为0。

       结构体内容

      sasl/sasl.h

      struct iovec

      {
           long iov_len;
           char *iov_base;
      };

      linux/sockt.h

      struct msghdr

      {
           void    *   msg_name;   /* Socket name          */ 

           int     msg_namelen;    /* Length of name       */
           struct iovec *  msg_iov;    /* Data blocks          */
           __kernel_size_t msg_iovlen; /* Number of blocks     */   

           void    *   msg_control;    /* Per protocol magic (eg BSD file descriptor passing) */
          __kernel_size_t msg_controllen; /* Length of cmsg list */
          unsigned    msg_flags;
     };

     使用:

     unsigned char buf[100];

     struct iovc iov;

     struct msghdr msg;

     iov.iov_base = buf;

     iov.iov_len = sizeof(buf);

     msg.msg_iov = &iov;

     msg.msg_iovlen = 1;

     recvmsg(fd, &msg, 0);

6.2、发送数据

    ssize_t write(int fildes, const void *buf, size_t nbyte);

    参数分析:

    files: 在服务器端是accept()返回的描述符,在客户端表示socket()返回的描述符。

    buf:用于保存发送数据的缓冲区;

    nbyte: 发送数据的长度;

 

    ssize_t sendmsg(int s, const struct msghdr *msg, int flags);

    s:在服务器端是accept()返回的描述符,在客户端表示socket()返回的描述符。

    msg:用于存储发送数据时的数据内容和长度;

    flags:发送标志,一般为0;

    使用介绍:

   

     unsigned char buf[100];

     struct iovc iov;

     struct msghdr msg;

     iov.iov_base = buf;

     iov.iov_len = sizeof(buf);

     msg.msg_iov = &iov;

     msg.msg_iovlen = 1;

     sendmsg(fd, &msg, 0);

 

7、适用于udp的数据交互

7.1、接受数据

      ssize_t recvfrom(int socket, void *restrict_buffer, size_t length, int flags,

                                struct sockaddr *restrict_address, socklen_t *restrict_address_len);

      参数分析:

      socket: 在服务器端是accept()返回的描述符,在客户端表示socket()返回的描述符。

      restrict_buf:用于保存接受到的数据;

      length:接受数据的长度;

      flags:标志位0;

      restrict_address: 用于存放对方的地址;

      restrict_address_len: 该结构体的长度

      发送数据:

     ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

     参数分析:

     如recvfrom()

 

三、一些其他函数

  1、int inet_pton(int family,const char * strptr,void * addrptr);

   返回:1---成功   0---输入不是有效的表达格式   -1---失败

   第一个参数可以是AF_INET或AF_INET6:第二个参数是一个指向点分十进制串的指针:第三个参数是一个指向转换后的网络字节序的二进制值的指针。

  使用:

  struct sockaddr_in server; 

  inet_pton(AF_INET, "192.168.1.177", &(server.sin_addr));

2、inet_ntop函数:和inet_pton函数正好相反,inet_ntop函数是将网络字节序二进制值转换成点分十进制串。

 
3、设置套接字选项

int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)

参数详解:

sockfd: socket描述符;

level:

level指定控制套接字的层次.可以取三种值:
1)SOL_SOCKET:通用套接字选项.
2)IPPROTO_IP:IP选项.
3)IPPROTO_TCP:TCP选项.

optname:指定控制的方式(选项的名称)

 

optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换 


选项名称        说明                  数据类型
========================================================================
            SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST      允许发送广播数据            int
SO_DEBUG        允许调试                int
SO_DONTROUTE      不查找路由               int
SO_ERROR        获得套接字错误             int
SO_KEEPALIVE      保持连接                int
SO_LINGER        延迟关闭连接              struct linger
SO_OOBINLINE      带外数据放入正常数据流         int
SO_RCVBUF        接收缓冲区大小             int
SO_SNDBUF        发送缓冲区大小             int
SO_RCVLOWAT       接收缓冲区下限             int
SO_SNDLOWAT       发送缓冲区下限             int
SO_RCVTIMEO       接收超时                struct timeval
SO_SNDTIMEO       发送超时                struct timeval
SO_REUSERADDR      允许重用本地地址和端口         int
SO_TYPE         获得套接字类型             int
SO_BSDCOMPAT      与BSD系统兼容              int
==========================================================================
            IPPROTO_IP
--------------------------------------------------------------------------
IP_HDRINCL       在数据包中包含IP首部          int
IP_OPTINOS       IP首部选项               int
IP_TOS         服务类型
IP_TTL         生存时间                int
==========================================================================
            IPPRO_TCP
--------------------------------------------------------------------------
TCP_MAXSEG       TCP最大数据段的大小           int
TCP_NODELAY       不使用Nagle算法             int
=========================================================================


 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值