一起talk C栗子吧(第一百四十九回:C语言实例--socket通信接口一)

时间:2020-12-14 10:57:19

各位看官们,大家好,上一回中咱们说的是socket通信的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们,我们在上一回中介绍了socket通信的步骤,当时提到了实现这些步骤使用的系统调用,当时有些看官不理解这些系统调用,今天我们趁热打铁来介绍这些系统调用。

int socket(int domain, int type, int protocol)
  • 该函数用来创建一个socket;
  • 该函数的三个参数分别对应socket的三个属性:域,类型和协议;
  • 该函数运行成功时返回套接字描述符,运行失败时返回-1;

使用该函数时需要包含的头文件为: #include <sys/socket.h>,该文件中包含了socket通信相关的系统调用,我们在本章回中介绍的系统调用都需要包含该头文件。此外,该函数的第三个参数通常为0,表示使用默认的通信协议。

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
  • 该函数用来在客户端和服务器端建立一个连接;
  • 该函数的第一个参数是客户端的套接字描述符;
  • 该函数的第二个参数是服务器端的地址,地址中包含着详细的服务器信息;
  • 该函数的第三个参数是服务器端地址的长度,也就是第二个参数的长度;
  • 该函数运行成功时返回0,运行失败时返回-1;
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
  • 该函数用来把服务器端的套接字和服务器的地址绑定在一起;
  • 该函数的第一个参数是服务器端的套接字描述符;
  • 该函数的第二个参数是服务器的地址,地址中包含着详细的服务器信息;
  • 该函数的第三个参数是服务器端地址的长度,也就是第二个参数的长度;
  • 该函数运行成功时返回0,运行失败时返回-1;
int listen(int sockfd, int backlog)
  • 该函数用来在服务器端创建套接字队列,以便服务器监听客户端发来的通信连接请求;
  • 该函数的第一个参数是服务器端的套接字描述符;
  • 该函数的第二个参数是套接字队列的长度,也就是服务器允许接受的通信连接请求数量;
  • 该函数运行成功时返回0,运行失败时返回-1;

关于服务器允许接受的通信连接请求数量是一个重要的数值,不能太大。设置该值时要参考服务器的负载能力和服务器的处理能力,不然会让服务器崩溃。服务器本质上也是一台电脑,只是性能比我们日常使用的电脑好一些,如果你在自己的电脑上打开成百上千个程序,电脑就会慢的像个蜗牛,甚至死机。同理,如果在服务器上打开的连接太多,服务器也会崩溃。这点我相信大家很容易理解,因此就不多说了。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
  • 该函数可以让服务器端接受客户端发来的连接请求,让服务器端和客户端建立连接;
  • 该函数的第一个参数是服务器端的套接字描述符;
  • 该函数的第二个参数是客户端的地址,注意不是服务器的地址;
  • 该函数的第三个参数是客户端地址的长度,也就是第二个参数所指向地址的长度;
  • 该函数运行成功时返回套接字描述符,运行失败时返回-1;

关于该函数要做以下的说明,就当作是一些注意事项吧:

  • 该函数的最后两个参数都是指针,调用该函数前所指的内容为空,调用该函数后会获取客户端的地址及其 长度。该指针所指区域需要容纳客户端地址,如果不想了解客户端的地址,使用空指针也是可以的。
  • 该函数创建了一个新的套接字,套接字的描述符就是它返回的套接字描述符,新套接字描述符的类型与服 务器端套接字描述符的类型相同。我们通过该套接字来与客户端进行通信,而服务器端原来的套接字,也 就是函数中第一个参数所代表的套接字则继续处于监听状态,准备接受客户端发来的其它请求。
  • 该函数具有阻塞功能,如果在listen创建的套接字队列中没有连接请求,那么就会阻塞,直到队列中有新的连接请求时才会运行。
int shutdown(int sockfd, int how)
  • 该函数用来关闭使用套接字建立的通信连接;
  • 该函数的第一个参数是套接字描述符,该函数将关闭与它关联的通信连接;
  • 该函数的第二个参数是关闭连接的方式,请参考下面的介绍;
  • 该函数运行成功时返回0,运行失败时返回-1,同时设置errno全局变量;

回想一下,我们在前面章回中介绍管道的时候,使用管道进行进程间通信时,管道是单向的,管道两端的任何一方只能读或者写操作,如果想在任何一方同时进行读写操作,那么就需要再建立一个管道。但是使用套接字建立的通信连接是双向的,也就是说我们在客户端或者服务器端中的任何一方都可以进行读写操作。使用close函数时会把套接字通信连接的两端都关闭,有时候我们只需要关闭其中的一端,这个时候该函数就派上了用场。我们通过该函数的第二个参数来控制关闭的方向,该参数的值可以是以下三种之一:

  • SHUT_RD(表示关闭连接的读方向,与此同时,连接的另一端不能通过该连接写数据)
  • SHUT_WR(表示关闭连接的写方向,与此同时,连接的另一端不能通过该连接读数据)
  • SHUT_RDWR(表示关闭连接的读写方向,与此同时连接的另一端不能通过该连接写数据和读数据)

该函数在操作上比close灵活一些,可以看作是对close函数的扩展。

各位看官,关于socket通信接口的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。