Socket中几个常用的API总结

版权声明:本BLOG上原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请争得本人同意,否则属于侵权行为。 https://blog.csdn.net/weixin_40204595/article/details/81809721

写在前面:总结一下几个常用的SOCKET API。

正文:


1、socket():
   函数原型:int socket(int domain,int type, int protocol);
   函数作用:用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源的函数
   参数:domain:协议族/域,通常AF_INET(IPv4)、AF_INET6(IPv6)
         type:是套接口类型,主要SOCK_STREAM(TCP协议)、SOCK_DGRAM(UDP协议)
         protocol:一般为0
   返回:成功时返回非负整数。     
2、htons():
   函数原型:uint16_t htons(uint16_t hostshort);
   函数作用:htons是将整型变量从主机字节顺序转变成网络字节顺序, 
   就是整数在地址空间存储方式变为高位字节存放在内存的低地址处,
   网络字节顺序采用big-endian排序方式。 

  inet_ntoa():

  函数原型:char *inet_ntoa(struct in_addr in);
  函数作用:将IP地址,转换为点分十进制的字符串格式;

注意为大端模式即0x78对应120,0x56对应86.......
3、inet_addr(): 
   原型:in_addr_t inet_addr(const char *cp);
   函数作用:inet_addr()的功能是将一个点分十进制的IP转换成一个长整数型数(u_long类型)。
   参数:字符串,一个点分十进制的IP地址。
4、select 函数以及 select相关函数:
   函数原型:  int select(int maxfdp, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout);
   函数作用:它能够监视我们需要监视的文件描述符的变化情况——读写或是异常
 
    两个结构体:struct fd_set  可以理解为一个集合,这个集合中存放的是文件描述符,
    fd_set集合可以通过一些宏由人为来操作,比如清空集合:FD_ZERO(fd_set*),
    将一个给定的文件描述符加入集合之中 FD_SET(int, fd_set*),
    将一个给定的文件描述符从集合中删除 FD_CLR(int,   fd_set*),
    FD_ISSET(int, fd_set*):检查集合中指定的文件描述符是否可以读写 ,
    即检查 int所对应的套接字是否在这个集合当中,
    select函数后将更新这个集合,把其中不可读的套节字去掉 。
 
 struct timeval是一个大家常用的结构,用来代表时间值,有两个成员,
 一个是秒数,另一个毫秒数,即select函数是非阻塞的,超过这个设定的时间后可退出。
 这个时间设置的用法:
 第一:若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,
 一定等到监视文件描述符集合中某个文件描述符发生变化为止;

 第二:若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,
 都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;

 第三:timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,
 超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
 
 参数解释:
 readfds:  (可选)指针,指向一组等待可读性检查的套接口;
 writefds: (可选)指针,指向一组等待可写性检查的套接口;
 exceptfds:(可选)指针,指向一组等待错误检查的套接口;
 timeout:   本函数最多等待时间,对阻塞操作则为NULL。
 
5、bind函数:
 函数原型:bind( SOCKET sockaddr, const struct sockaddr my_addr,int addrlen);
 函数作用:套接字绑定到一个地址,并制定一个端口号。
 将套接字绑定一个IP地址和端口号,因为这两个元素可以在网络环境中唯一地址表示一个进程。
6、listen函数:
 函数原型:int listen(SOCKET sockfd, int backlog);
 函数作用:listen函数使用主动连接套接字变为被连接套接口,使得一个进程可以接受其它进程的请求,
 从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。
 listen函数一般在调用bind之后-调用accept之前调用。
7、accept函数:
 函数原型: int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen)。
 函数作用:在服务器端,socket()返回的套接字用于监听(listen)和接受(accept)客户端的连接请求。
 这个套接字不能用于与客户端之间发送和接收数据。
 accept()接受一个客户端的连接请求,并返回一个新的套接字。
 所谓“新的”就是说这个套接字与socket()返回的用于监听和接受客户端的连接请求的套接字不是同一个套接字。
 与本次接受的客户端的通信是通过在这个新的套接字上发送和接收数据来完成的。
 accept()函数仅被TCP类型的服务器程序调用,从已完成连接队列返回下一个建立成功的连接,
 如果已完成连接队列为空,线程进入阻塞态睡眠状态。成功时返回套接字描述符,错误时返回-1。
 如果accpet()执行成功,返回由内核自动生成的一个全新socket描述符,
 用它引用与客户端的TCP连接。通常我们把accept()第一个参数成为监听套接字(listening socket),
 把accept()功能返回值成为已连接套接字(connected socket)。
 一个服务器通常只有1个监听套接字,监听客户端的连接请求;
 服务器内核为每一个客户端的TCP连接维护1个已连接套接字,用它实现数据双向通信。
8、setsockopt()函数:
 函数原型:int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);
 函数作用:设置与某个套接字关联的选项,例如:recv等函数默认为阻塞模式(block),即直到有数据到来之前函数不会返回,
 而我们有时则需要一种超时机制使其在一定时间后返回而不管是否有数据到来,这里我们就会用到setsockopt()函数。
 参数:
 sock:将要被设置选项的套接字。
 level:选项所在的协议层,可以取三种值:
    1)SOL_SOCKET:通用套接字选项.
    2)IPPROTO_IP:IP选项.
    3)IPPROTO_TCP:TCP选项. 
 optname:指定控制的方式,根据level的不同,可以由如下配置方式:
    选项名称        说明                  数据类型
========================================================================
            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
========================================================================
    optval:根据optname的不同,这个参数也不一样,例如当optname为 SO_RCVTIMEO 超时接受时,optval可以为
         struct timeval
        {
                time_t tv_sec;
                time_t tv_usec;
        };
    这种类型的结构体,表示满足一定时间后退出。
    optlen:optval的长度。

9、fcntl()函数:

    函数原型:int fcntl(int fd, int cmd, long arg);

    函数作用:可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的的各种属性。

    参数:fd,socket函数返回的描述符;

              cmd,这里先用两个cmd举例,

                         F_GETFL:获取文件打开方式的标志。

                         F_SETF :设置文件打开方式为第三个参数arg指定方式

    通常用这个函数来设置阻塞性质,举例:

  int flags = fcntl(socket, F_GETFL, 0); //将文件描述符的标志保存到flags中

  /* 设置为非阻塞*/

 if (fcntl(socket_descriptor, F_SETFL, flags | O_NONBLOCK) < 0)

 {

/* Handle error */

 }

/* 设置为阻塞 */

if ((flags = fcntl(sock_descriptor, F_SETFL, 0)) < 0)

{

/* Handle error */

}

                         

    
    
总结:
TCP编程的服务器端一般步骤是:

1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt(); * 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、开启监听,用函数listen();
5、接收客户端上来的连接,用函数accept();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
8、关闭监听;
TCP编程的客户端一般步骤是:

1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
 
UDP编程的服务器端一般步骤是:

1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;

UDP编程的客户端一般步骤是:

1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;
    
 
 
 

猜你喜欢

转载自blog.csdn.net/weixin_40204595/article/details/81809721