TCP/IP(7)-TCP Server与TCP Client(linux套接字)

前面几篇文章谈到的关于TCP/IP应用层以下的协议,这些协议最终是在操作系统内核中实现的,套接字API是unix系统用于网络连接的接口,后来被移植到windows系统中,就有了winsock。

TCP的Client/Server模式

在TCP/IP协议中已经讲解了TCP协议中三次握手和四次握手过程,以及发送消息和接受消息。那么在linux系统中,内核中已经将这些协议实现,现在我们一起看看linux下套接字编程的API。

TCP服务器端

1. 创建套接字

 #include <sys/socket.h>
 int socket(int family,int type,int protocol);    
      返回:非负描述字---成功   -1---失败

第一个参数指明了协议簇,目前支持5种协议簇,最常用的有AF_INET(IPv4协议)和AF_INET6(IPv6协议);第二个参数指明套接口类型,有三种类型可选:SOCK_STREAM(字节流套接口)、SOCK_DGRAM(数据报套接口)和SOCK_RAW(原始套接口);如果套接口类型不是原始套接口,那么第三个参数就为0。

2.绑定套接字
把一个套接字地址(本机IP和端口号)绑定到创建的套接字上。绑定套接字时可以选择指定IP地址和端口,也可以不指定。通配的IP地址用INADDR_ANY表示,通配的端口用0表示,通配的情况下由内核为其指定相应的IP地址和端口号。
对于客户端可以绑定套接字,但是一般不需要,因为客户端的端口号只是临时的,由内核来分配更合理。但是对服务器而言,一般要使用知名端口号,如果不进行绑定,客户端不知道目的端口号,连接不能完成。
这里写图片描述
通配地址实现:htonl(INADDR_ANY)
通配地址,内核将等到套接字已连接TCP或已经发出数据报(UDP)时才指定。

#include <sys/socket.h>  
int bind(int sockfd, const struct sockaddr * server, socklen_t addrlen);
 返回:0---成功   -1---失败 

3.监听
socket创建的套接字是主动套接字,调用listen后变成监听套接字。TCP状态有CLOSE跃迁到LISTEN状态。
backlog是已完成队列和未完成队列大小之和,对于监听套接字有两个队列,一个是未完成队列,一个是已完成队列。

  • 未完成队列:客户端发送一个SYN包,服务器收到后变成SYN_RCVD状态,这样的套接字被加入到未完成队列中。
  • 已完成队列:TCP已经完成了3次握手后,将这个套接字加入到已完成队列,套接字处于ESTABLISHED状态。
    这里写图片描述

下图中可以看出,TCP的三次握手是在调用connect函数时完成的,服务器端没有调用函数,但是必须有套接字在某个端口监听,不然会返回客户端RST,终止连接。
这里写图片描述

#include<sys/socket.h>
int listen(int sockfd, int backlog);

调用listen函数后的套接字称为监听套接字。

4.accept函数
accept函数从已完成连接的队列中取走一个套接字,如果该队列为空,则accept函数阻塞。accept函数的返回值称为已连接套接字,已连接的套接字就建立一个完整的TCP连接,源IP地址,源端口号,目的IP地址,目的端口号都是唯一确定了。

#include <sys/socket.h>         
int accept(int listenfd, struct sockaddr *client, socklen_t * addrlen);  

5.数据传输

  • write和read函数:当服务器和客户端的连接建立起来后,就可以进行数据传输了,服务器和客户端用各自的套接字描述符进行读/写操作。因为套接字描述符也是一种文件描述符,所以可以用文件读/写函数write()和read()进行接收和发送操作。

write()函数用于数据的发送

#include <unistd.h>         
 int write(int sockfd, char *buf, int len); 
  回:非负---成功   -1---失败

参数sockfd是套接字描述符,对于服务器是accept()函数返回的已连接套接字描述符,对于客户端是调用socket()函数返回的套接字描述符&

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值