做门户网站的公司,宝安有效的网站制作,中国建设信息网官网八大员证查询,公众号如何推广宣传一、TCP编程流程
TCP 提供的是面向连接的、可靠的、字节流服务。TCP的服务器端和客户端编程流程如下#xff1a; 1.socket()方法
用来创建一个套接字#xff0c;有了套接字就可以通过网络进行数据的收发。这也是为什么进行网络通信的程序首先要创建一个套接字。创建套接字时…一、TCP编程流程
TCP 提供的是面向连接的、可靠的、字节流服务。TCP的服务器端和客户端编程流程如下 1.socket()方法
用来创建一个套接字有了套接字就可以通过网络进行数据的收发。这也是为什么进行网络通信的程序首先要创建一个套接字。创建套接字时要指定使用的服务类型使用基于TCP协议的流式服务SOCK_STREAM。
2.bind()方法
用来指定套接字使用的IP地址和端口。IP地址就是自己主机的地址如果主机没有接入网络测试程序时可以使用回环地址“127.0.0.1”。端口是一个16位的整形值一般0-1024 为知名端口如HTTP使用的80号端口。这类端口一般用户不能随便使用。其次1024-4096 为保留端口用户一般也不使用。4096以上为临时端口用户可以使用。在Linux 上1024 以内的端口号只有root用户可以使用。
3.listen()方法
用来创建监听队列。监听队列有两种一个是存放未完成三次握手的连接一种是存放已完成三次握手的连接。listen()第二个参数就是指定已完成三次握手队列的长度。
4.accept()方法
处理存放在 listen 创建的已完成三次握手的队列中的连接。每处理一个连接则accept()返回该连接对应的套接字描述符。如果该队列为空则accept阻塞。
5.connect()方法
一般由客户端程序执行需要指定连接的服务器端的IP地址和端口。该方法执行后会进行三次握手 建立连接。 6.send()方法
向TCP连接的对端发送数据。send()执行成功只能说明将数据成功写入到发送端的发送缓冲区中并不能说明数据已经发送到了对端。send()的返回值为实际写入 到发送缓冲区中的数据长度。
7.recv()方法
接收TCP连接的对端发送来的数据。recv()从本端的接收缓冲区中读取数据如果接收缓冲区中没有数据则recv()方法会阻塞。返回值是实际读到的字节数如果 recv()返回值为 0 说明对方已经关闭了TCP连接。 close()方法用来关闭TCP连接。此时会进行四次挥手。 二、服务器端和客户端连通
服务器端代码ser.c如下
#includestdio.h
#includestdlib.h
#includestring.h
#includeunistd.h
#includesys/socket.h
#includenetinet/in.h
#includearpa/inet.hint main()
{//1.创建套接字int sockfd socket(AF_INET,SOCK_STREAM,0);//第一个参数协议族AF_INET代表IPV4网络协议//第二个参数套接字的服务类型SOCK_STREAM代表基于TCP协议的流式服务的套接字//第三个参数0表示使用默认协议if(sockfd-1){printf(创建失败\n);exit(1);}struct sockaddr_in saddr,caddr;//定义服务端和客户端的套接字地址memset(saddr,0,sizeof(saddr));//套接字在使用之前必须清空saddr.sin_familyAF_INET;saddr.sin_porthtons(6000);//短整型主机字节序转网络字节序saddr.sin_addr.s_addr inet_addr(127.0.0.1);//ip地址//2.指定套接字地址int resbind(sockfd,(struct sockaddr*)saddr/*将专用的套接字地址强转为通用的地址*/,sizeof(saddr));//第一个参数需要绑定的套接字描述符//第二个参数指向结构体变量saddr,并强转为struct sockaddr类型然后将ip和端口传给bind函数进行绑定//第三个参数第二个参数所指向的结构体的大小即套接字地址的长度if(res-1){printf(绑定失败\n);exit(1);}//3.创建监听队列存放要连接的客户端res listen(sockfd,5);//第一个参数被监听的套接字描述符//第二个参数表示处于完全连接状态的套接字的上限if(res-1){exit(1);}while(1){socklen_t lensizeof(caddr);//4.接受客户端的连接int caccept(sockfd,(struct sockaddr*)caddr,len);//如果accept成功返回一个新的套接字描述符c与客户端通信这个新的套接字描述符是内核自动生成的//第一个参数是服务器端的套接字描述符//第二个参数用于返回客户端的套接字地址cadrr//第三个参数客户端套接字地址的长度if(c0){continue;}printf(accept c%d,ip%s,port%d\n,c,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));char buff[128]{0};//5.接收客户端的数据recv(c,buff,127,0);//第一个参数已连接客户端的那个新的套接字描述符//第二个参数指定接收客户端数据的位置//第三个参数指定接收客户端发来的数据的大小//第四个参数一般设置为0printf(buff%s\n,buff);//6.向客户端发送反馈数据send(c,ok,2,0);//第一个参数已连接客户端的那个新的套接字描述符//第二个参数指定向客户端发送数据的位置也可以直接指定内容//第三个参数指定向客户端发送数据的大小//第四个参数一般设置为0//7.关闭与客户端通信的套接字close(c);}}客户端代码cli.c如下
#includestdio.h
#includestdlib.h
#includestring.h
#includeunistd.h
#includesys/socket.h
#includenetinet/in.h
#includearpa/inet.hint main()
{//1.创建套接字int sockfdsocket(AF_INET,SOCK_STREAM,0);if(sockfd-1){exit(1);}struct sockaddr_in saddr;memset(saddr,0,sizeof(saddr));saddr.sin_familyAF_INET;saddr.sin_porthtons(6000);saddr.sin_addr.s_addrinet_addr(127.0.0.1);//2.向服务器端发起连接int resconnect(sockfd,(struct sockaddr*)saddr,sizeof(saddr));//第一个参数客户端套接字的描述符//第二个参数服务器套接字的地址//第三个参数服务器套接字地址的大小if(res-1){printf(连接失败\n);exit(1);}printf(输入);char buff[128]{0};fgets(buff,128,stdin);//3.向服务器端发送数据send(sockfd,buff,strlen(buff),0);//第一个参数已被服务器端连接的客户端的套接字描述符//第二个参数指定向服务器端发送的数据的位置//第三个参数指定向服务器端发送的数据的大小//第四个参数一般设置为0memset(buff,0,sizeof(buff));//4.接收服务器反馈回来数据recv(sockfd,buff,127,0);//第一个参数已被服务器端连接的客户端的套接字描述符//第二个参数指定服务器端反馈回来的数据的位置//第三个参数指定服务器端反馈回来的数据的大小//第四个参数一般设置为0printf(buff%s\n,buff);//5.关闭连接close(sockfd);exit(0);
}运行结果
先编译运行ser.c使服务器端启动 再打开另一个终端编译运行cli.c使客户端启动此时服务器端显示已经接收到了客户端的连接 然后客户端向服务器端发送数据 如上图所示客户端向服务端发送信息hello服务器端向客户端反馈信息ok。