TCP服务器实现过程
(1)创建套接字:socket函数
(2)给套接字绑定ip地址和端口号:bind函数
(3)将套接字文件描述符,从主动变为被动文件描述符(做监听准备):listen函数
(4)被动监听客户的连接并响应:accept函数
(5)服务器调用read(recv)和write(send),收发数据,实现与客户的通信
(6)调用close或者shutdown关闭TCP的连接
1、头文件:#include
2、函数原型:int socket(int domain, int type, int protocol);
3、函数形参:domian:族/范围;
type:套接字类型;
protocol:一般置为零。
注:(1)domian :指定协议族AF_INET(IPV4:ip 32位)、 AF_INET6(IPV6:ip 128位)。
(2)type:进一步指定使用协议族中的哪个子协议来通信。
常见设置:SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)、SOCK_RDM(原始网络通信)、SOCK_NONBLOCK(非阻塞、可与其他|运算)、
SOCK_CLOEXEC(表示一旦进程exec执行新程序后,自动关闭socket返回的“套接字文件描述符”,”可与其他|运算)
4、函数返回值:成功返回套接字文件描述符,失败返回-1,errno被设置。
1、头文件:#include
2、函数原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
3、函数形参:sockfd:socket所返回的套接字文件描述符
addr:保存ip地址及端口号的结构体的地址;
addrlen:第二个结构体参数的长度。
注:add结构体成员: (使用需加头文件#include
struct sockaddr_in{
sa_family_t sin_family; //设置AF_***(地址族)
__be16 sin_port; //设置端口号
struct in_addr sin_addr; //设置Ip
/* 设置IP和端口时,这个成员用不到,这个成员的作用后面再解释, */
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)];
};
struct in_addr{
__be32 s_addr; //__be32是32位的unsigned int,因为IPV4的ip是32位的无符号整形数
};
4、函数返回值:成功返回0,失败返回-1,errno被设置。
5、功能:将指定了通信协议(TCP)的套接字文件与IP以及端口绑定起来。
6、字节序转化:网络字节序采用大端字节序
7、ip地址格式转化
1、头文件:#include
2、函数原型:int listen(int sockfd, int backlog);
3、函数形参:sockfd:socket所返回的套接字文件描述符;
backlog:指定队列的容量。
注:backlog:队列用于记录正在连接,但是还没有连接完成的客户,一般将队列容量指定为2、3。
该容量并无统一的设定值,一般来说只要小于30即可。
4、函数返回值:成功返回0,失败返回-1,ernno被设置
5、功能:
将套接字文件描述符,从主动文件描述符变为被动描述符,然后用于被动监听客户的连接。socket返回的“套接字文件描述符”默认是主动的,如果你想让它变为被动的话,你需要自己调用listen函数来实现。
注:服务器调用accept函数监听客户连接,而客户端则是调用connect来连接请求的。
1、头文件:#include
2、函数原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
3、函数形参:sockfd:socket所返回的套接字文件描述符
addr:保存ip地址及端口号的结构体的地址;
addrlen:第二个结构体参数的长度,要求给的是地址。
4、函数返回值:成功返回一个通信描述符,专门用于与该连接成功的客户的通信,失败返回-1,ernno被设置。
注:后续服务器与该客户间正式通信,使用该accept返回的“通信描述符”来实现。
5、功能:
(1)被动监听客户发起三次握手的连接请求,三次握手成功,即建立连接成功。
(2)accept被动监听客户连接的过程,其实也被称为监听客户上线的过程。
(3)对于只连接了一半,还未连接完成的客户,会被记录在未完成队列中,队列的容量由listen函数的第二个参数(backlog)来指定。
注:主动描述符可以主动的向对方发送数据。被动描述符只能被动的等别人主动想你发数据,然后再回答数据,不能主动的发送数据。
TCP客户端的实现过程
(1)用socket创建套接字文件,指定使用TCP协议
(2)调用connect主动向服务器发起三次握手,进行连接
(3)调用read(recv)和write(send)收发数据
(4)调用close或者shutdown关闭连接
1、头文件:#include
2、函数原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
3、函数形参:sockfd:socket所返回的套接字文件描述符
addr:保存用于设置所要连接服务器的IP和端口的结构体地址;
addrlen:第二个结构体参数的长度。
4、函数返回值:成功返回0,失败返回-1,ernno被设置。
注:后续服务器与该客户间正式通信,使用该accept返回的“通信描述符”来实现。