套接字编程3(tcp)
Posted 李憨憨_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了套接字编程3(tcp)相关的知识,希望对你有一定的参考价值。
tcp通信程序的编写:
第一步在内核里创建了一个套接字socket结构体, 第二步绑定地址信息, 我们相当于有了源端IP(sip)和源端端口(sport), 下一步就是监听, 监听就是将tcp的状态置为listen状态, listen状态的套接字才会处理客户端的连接请求. 这一步完成之后, 我们的网卡是不断从网络上接收数据的. 这时候如果有一个客户端, 客户端给主机发送了一个tcp链接建立请求(syn), 不管是什么请求, 它都是一条数据, 作为一条数据那么就有源端地址信息和对端地址, 有了对端地址信息最终就会到网卡上.
假设我的监听地址信息是192.168.2.2:8000, 对端端口的地址信息是192.168.2.3:9000用的协议是tcp协议. 源端地址+源端端口+对端地址+对端端口+协议是一个五元组, 五元组就标识了一个通信.
这条数据经过网卡发送就到达了这边主机, 操作系统收到这条数据之后, 通过目标地址和端口来确定是这个socket的数据, 这个数据就会被放到socket的接收缓冲区里, socket就会发现这个数据是一个连接请求, 就会处理这个连接请求.
处理这个请求, 就会为我们的这个客户端又单独创建了一个套接字, 将上边的套接字复制了一份出来, 新建的这个socket不仅有源端的地址和端口, 还包含了对端的地址和端口(dip+dport)
原来的套接字只用于接收新的连接请求, 新建的套接字是专门用来跟指定的客户端来进行通信的
客户端如果在服务端进入监听状态之前发送连接请求, 服务端是不会处理这个连接请求的, 这个请求会被直接丢弃.
接口认识
1.创建套接字:
int socket(int domain, int type, int protocol)
套接字类型是流式套接字, 协议类型是tcp协议;
2.绑定地址:
int bind(int sockfd, struct sockaddr *addr, socklen_t len);
3.开始监听
int listen(int sockfd, int backlog)
sockfd: 描述符; backlong:服务端能够在同一时间处理的最大连接数
3.客户端发送连接请求
int connect(int sockfd, struct sockaddr *srvaddr, socklen_t len)
sockfd: 描述符; srvaddr: 服务端地址信息; len: 地址长度
返回值: 成功返回0; 失败返回-1;
4.服务端获取新建连接
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen)
sockfd: 监听套接字–服务端最早创建的套接字–只用于获取新建连接
cliaddr: 新的连接的客户端地址信息;
addrlen: 输入输出参数, 指定地址信息长度, 以及返回实际长度
返回值: 新建连接的套接字描述符—往后与客户端的通信都通过这个描述符完成
5.收发数据
ssize_t send(int sockfd, void *data, int len, int flag);
sockfd: 套接字描述符; data: 要发送的数据;
len: 数据长度; flag: 0;
返回值: 成功返回实际发送的数据长度; 失败返回-1; 连接断开会触发异常;
ssize_t recv(int sockfd, void *buf, int len, int falg)
sockfd: 描述符; buf: 空间地址;
len: 要接收的数据长度; flag: 0;
返回值: 成功返回实际接收的数据长度; 出错返回-1; 连接断开返回0;
tcp通信因为socket结构中包含完整五元组因此不需要指定地址
6.关闭套接字
int close(sockfd);
以上是关于套接字编程3(tcp)的主要内容,如果未能解决你的问题,请参考以下文章