TCP client和server 程序例子(转)

时间:2022-12-01 17:22:26
tcp和udp的程序就不贴了,网上例程太多,放在附件里。下面分别说一下流程和细节
tcp服务端流程:
1、建立socket( socket 函数)
2、设置服务端sockaddr_in结构体,并绑定到第一步的socket(bind函数)
3、设置客户端信息队列长度,也就是已经建立连接的客户端和未连接上客户端的最大数量,并把socket设为侦听状态(listen函数)
4、等待客户端连接,并得到与该客户端绑定的socket(accept函数)
5、收发数据(sendrecv函数
6、关闭绑定客户端的socket,关闭侦听socket(close函数)
tcp客户端流程:

1、创建socket

2、设置要连接的服务器ip地址和端口到sockaddr_in结构体

3、连接服务器(connect函数)

4、收发数据

5、关闭客户端socket
tcp连接时的三次握手:
客户端connect时发出syn信号给服务端,服务端收到后返回ack信号和syn信号,客户端收到后发送ack信号给服务端。
可以用两个人在线语音形象的描述三次握手
我对你说:能听到我说话吗(syn)?你听到后跟我说:能听到(ack),那你能听到我说话吗(syn)?我听到后跟你说:能听到(ack)。这就确保了信号在你和我之间的双向连通
tcp断开时的四次握手:
A端发出fin信号,B端收到后返回ack信号,B端再发fin信号,A端收到后返回ack信号。这里的fin只是代表单边结束,因为tcp是全双工,所以必须两端都断开才断开。断开之后在read会得到一个数据长度0的包,可以用来处理断开之后的事情

细节:
主要是网络字节序的问题,需要把sockaddr_in中的ip和port转换为网络字节序也就是大端模式,例如:htons(port_number),在sockaddr_in中的端口号是一个short类型,因此是htons(host to net short)。
转换ip的函数有inet_addr、inet_aton、inet_pton,其中inet_pton比较新,ipv6也可以用,具体使用方法看man手册。

UDP服务端:

1、创建socket
2、设置服务端sockaddr_in结构体,并绑定到第一步的socket(bind函数)
3、等待客户端连接,获得客户端sockaddr结构体从而知道ip和端口

4、收发数据recvfromsendto函数)
5、关闭服务端socket
UDP
客户端

1、创建socket
2、设置要连接的服务器ip地址和端口到sockaddr_in结构体
3、收发数据
4、关闭客户端socket
细节:
除了网络字节序最主要的点就是recvfrom这个函数出错返回后perror打印出的的invalid argument错误,原因是ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen)这个函数里面的addrlen在使用之前必须先初始化为sockaddr结构体的长度,函数执行之后会变成src_addr的真实长 度。如果不初始化,程序能不能执行全凭运气...
man recvfrom中关于addrlen参数的说明:
If  src_addr  is  not  NULL,  and  the underlying protocol provides the
source address, this source address is filled  in.   When  src_addr  is
NULL,  nothing  is  filled  in;  in this case, addrlen is not used, and
should also be NULL.  The argument addrlen is a value-result  argument,
which  the  caller should initialize before the call to the size of the
buffer associated with src_addr, and modified on return to indicate the
actual  size  of the source address.  The returned address is truncated
if the buffer provided is too small; in this case, addrlen will  return


a value greater than was supplied to the call.