2.调用bind函数将这个套接字绑定ip和端口号,注意此时的ip和端口号都是服务器自己的端口号和ip,因为服务器是被动的连接,生成的是监听套接字,监听的是客户端发来的要连接的服务器的ip和端口号,监听套接字会查看自己绑定的ip和端口号和客户端发来的要连接的服务器的ip和端口号是否和自己一样,才能决定是否接受连接
3.调用listen函数,使得套接字变成一个被动的监听套接字,使已绑定的套接字等待监听客户端的连接请求,并设置服务器同时可以连接的数量(已连接队列和未连接队列),当监听到客户端发来的ip和端口号与未连接队列中的套接字吻合时,就把客户端发来的套接字信息放到已连接队列当中
4.调用accept函数,如果listen已连接队列中没有请求的话,该函数会阻塞,直到连接队列发来信息,该函数的第一个参数用来标识服务端套接字,第二个参数用来保存客户端套接字,实际上accept函数指定了服务器接收客户端的连接,并将客户端的套接字信息(ip和端口)保存了下来,因为当服务器给客户端发送数据的时候需要知道客户端的ip和端口
- 值得注意的是,accept会生成一个新的套接字链接,这个套接字已经连接了服务器和客户端,原来的监听套接字和客户端的连接就会断开,以后的通信就是新的连接套接字和客户端进行通信
- 为什么要建立一个新的套接字呢?因为监听套接字有自己的工作,还需要监听其他来访的客户端的连接请求,如果用监听套接字和客户端进行通信,那么其他客户端想要连接该服务器的端口就不会成功,影响很大
6.通信结束后,调用 close 函数关闭侦听 socket
客户端:
1. 调用 socket函数创建客户端 socket2. 调用 connect 函数尝试连接服务器3. 连接成功以后调用 send 或 recv 函数开始与服务器进行数据交流4. 通信结束后,调用 close 函数关闭侦听socket
文章插图
TCP相关的套接字APITCP是面向连接的,不同于UDP,TCP需要创建好套接字并且绑定端口号,绑定好之后,还需要进行监听,等待并获取连接 。
- listen
int listen(int sockfd, int backlog);功能: 将套接字设置为监听状态,监听socket的到来参数: sockfd:要设置的套接字(称为监听套接字) backlog:连接队列的长度返回值:成功返回0,失败返回-1
- accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能: 接受请求,获取建立好的连接参数: sockfd:监听套接字 addr:获取客户端的ip和端口信息(ipv4套接字结构体地址) addrlen:ipv4套接字结构体的大小的地址socklen_t addrlen = sizeof(struct sockaddr);返回值:成功返回一个连接套接字,用来标识远端建立好连接的套接字,失败返回-1
- connect
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能: 发起请求,请求与服务器建立连接(一般用于客户端向服务端发送请求)参数: sockfd:套接字,发起连接请求的套接字addr:ipv4套接字结构体的地址,描述自身的相关信息,用来标识自身,需要自己填充,让对端知道是请求方的信息,以便进行响应addrlen:描述addr的大小(ipv4套接字结构体的长度)返回值: 成功返回0,失败返回-1
思考一下:不知道大家是否对accept
会有疑惑,已经通过socket
创建好了一个套接字,accept又返回了一个套接字,这两个套接字有什么区别吗?UDP只有一个套接字就可以进行通信了,而TCP还需要这么多个,这是为什么?
经验总结扩展阅读
- 抓包分析 TCP 握手和挥手
- 概念+协议的了解+OSI七层模型,TCP/IP五层协议,网络数据传输流程 Linux--网络基础
- 关于网页实现串口或者TCP通讯的说明
- 如何kill一条TCP连接?
- TCP 序列号和确认号是如何变化的?
- 2d游戏怎么编程(怎么编写一个2d游戏)
- 怎么编写游戏程序(游戏外挂编写教程)
- Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog
- 手写编程语言-如何为 GScript 编写标准库
- 编写HelloWorld并运行