基本TCP套接字编程

经过最近一段时间的系统学习,对于传输协议中TCP协议的套接字编程以及11中状态转化有了一定的认识,现在做出

以下总结:

上图是几乎所有教科书上关于TCP客户端/服务器通信过程中API函数的汇总。

首先看服务器端

1:服务端以被动连接的方式参与通信,因此首先调用socket(int family,int type,int protocol)函数,其目的是在服务端创建一个socket文件描述符,该文件描述符同时也是该服务器的监听套接字描述符。其三个参数的含义分别为协议族,字节流,0。

2:服务端创建socket文件描述符之后,紧接着调用bind(int sockfd,const struct sockaddr *myaddr,socklen_t addrlen)函数,其目的是初始化上一步中创建的socket,具体是指定sockaddr指针中的地址族,ip地址,端口。

3:在bind函数之后,服务器调用listen(int sockfd,int backlog)函数,主要作用是让内核为监听套接字描述符创建两个队列,一个为半连接队列,一个是全连接队列,此时服务器才能处于监听状态,同时可以对客户端的连接做出响应,在listen之前,客户端以任何形式发送的数据都将被丢弃。

4:处于监听状态之后服务器可以选择接受客户端的连接,accept(int sockfd,struct sockaddr *cliaddr,socklen_t addrlen)函数,主要目的是为了返回一个已连接套接字描述符。同时三次握手完成,一条全连接建立。注意:一个服务器只有一个监听套接字,但是可以有多个已连接套接字。同时提醒上图的错误,在服务器处于监听状态之后,任何客户端就可以向服务器发起主动连接请求,同时该链接进入在listen()中创建的半连接队列,等accept()之后,即可进入全连接队列。

5:接下来就是循环read()write(),直到客户端主动关闭,或者因服务器异常被动关闭连接。

接着看客户端:与服务器端相比,客户端在TCP连接中的工作就少了很多,这也是为什么服务器的性能要比我们个人PC强大那么多的一个原因。

1:因为通信的实质就是两个套接字之间的通信,因此客户端第一步就是创建自己的socket(),与服务器中的socket一样,不在赘述。

2:待客户端创建完成自己的socket之后,紧接着就进行connect(int sockfd,const struct sockaddr *servaddr,socklen_t addrlen)连接到服务器的socket,具体状态在下一篇文章中详谈。注意:当服务器处于监听之后客户端就可以进行connect了。

个人水平有限,望各位海涵勿喷!