面向连接的套接字通信
1. 面向连接的套接字通信工作流程
(1) 服务器先也能够socket函数来建立一个套接字,用这个套接字完成通信的监听。
(2) 用bind函数来绑定一个端口号和IP地址。
(3) 服务器调用listen函数,使服务器的这个端口和IP处于监听状态,等待客户机的连接。
(4) 客户机用socket函数建立一个套接字,设定远程IP和端口。
(5) 客户机调用connect函数连接远程计算机指定的端口。
(6) 服务器用accept函数来接收远程计算机的连接,建立起于客户机之间的通信。
(7) 建立连接以后,客户机用write函数向socket中写入数据,也可以用read函数读取服务器发送方来的数据。
(8) 服务器用read函数读取客户机发送来的数据,也可以用write函数来发送数据。
(9) 完成通信以后,用close函数关闭socket关闭连接。
3. 绑定端口
绑定端口指的是将套机字与指定的端口相连。绑定端口函数bind。
int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
参数列表:sockfd:已经建立的socket编号,sockaddr:是一个指向sockaddr结构体类型的指针。在使用这个函数之前,需包含头文件<sys/types.h>、<sys/socket.h>。
4. 监听与连接
监听:指的是socket的端口处于等待状态,如果有客户端有连接请求,这个端口会接受这个连接。
(1) 等待监听函数
int listen(int s, int backlog);
参数列表:s是已经建立的socket,backlog是能同时处理得最大连接要求。
(2) 接受连接函数
服务器处于监听状态时,如果获得客户机的请求,会将这个请求放在等待队列中。当系统空闲时,将处理客户机的连接请求。
Int accept(int s, struct sockaddr *addr, int *addrlen);
当accept函数接受一个连接时,会返回一个新的socket编号。以后的数据传输与读取就是通过这个新的socket编号来处理的。
(3) 请求连接函数
请求连接:指的是客户机需要向服务器发送信息时,需要发送一个连接请求。
Int connect (int sockfd, struct sockaddr *serv_addr,int addrlen);
5. 数据的发送和接收
(1) 数据接受函数
函数recv可以接收远程主机发送来的数据,并把这些数据保存到一个数组中。
int recv(int s, void *buf,int len,unsigned int flags);
参数:flags一般设置为0,其他可能的赋值与含义如下所示:
MSG_OOB:接收以out-of-band送出的数据。
MSG_PEEK:返回来的数据并不会在系统内删除,如果再调用recv时会返回相同的数据内容。
MSG_WAITALL:强迫接收到len大小的数据后才能返回,除非有错误或信号产生。
MSG_NOSIGNAL:此操作被SIGPIPE信号中断。
该函数会返回接收到的字符数,如果错误则会返回-1。
(2) 信息发送函数send
用connect函数连接到远程计算机以后,可以用send函数将信息发送到对方的计算机。
int send(int s, const void *msg, int len, unsigned int flags);
参数:flags一般设置为0,其他可能的赋值与含义如下所示:
MSG_OOB:发送的数据以out-of-band方式送出。
MSG_DONTROUTE:取消路由表查询。
MSG_DONTWAIT:设置为不可阻断传输。
MSG_NOSIGNAL:此传输不可被SIGPIPE信号中断。
该函数会返回已传送的字符数,如果错误则会返回-1。
(3) 数据传输函数wirte与read
socket建立以后,向这个socket中写入数据表示向远程主机传送数据,从socket中读取数据相当于接受远程主机传送过来的数据。
size_t write(int fd, const void *buf, size_t count);
size_t read(int fd, void *buf, size_t count);
参数列表:fd是已经建立的socket,buf是指向一段内存的指针,count表示buf指向内存的长度。Read函数读取字节时,会把读取的内容保存到buf指向的内存中,然后返回读取到字节的个数,使用write函数传输数据时,会把buf指针指向的内存中的数据发送到socket连接的远程主机,然后返回实际发送字节的个数。需包含头文件<unistd.h>。