Webserver(4.3)TCP通信实现
目录
- 服务器端
- 客户端
- TCP三次握手
- 滑动窗口
- TCP四次挥手
服务器端
#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
//1.创建socket(用于监听的套接字)
int lfd=socket(AF_INET,SOCK_STREAM,0);
if(lfd==-1){
perror("socket");
exit(0);
}
//2.绑定
struct sockaddr_in saddr;
saddr.sin_family=AF_INET;
//indet_pton(AF_INET,"192.168.227.129",saddr.sin_addr.s_addr);
saddr.sin_addr.s_addr=INADDR_ANY;
saddr.sin_port=htons(9999);
int ret=bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr));
if(ret==-1){
perror("bind");
exit(0);
}
//3.监听
ret=listen(lfd,8);
if(ret==-1){
perror("listen");
exit(0);
}
//4.接收客户端的连接
struct sockaddr_in clientaddr;
socklen_t len=sizeof(clientaddr);
int cfd=accept(lfd,(struct sockaddr *)&clientaddr,&len);
if(cfd==-1){
perror("accept");
exit(0);
}
//输出客户端的信息
char clientIP[16];
inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,clientIP,sizeof(clientIP));
unsigned short clientPort =ntohs(clientaddr.sin_port);
printf("client ip is %s,port is %d\n",clientIP,clientPort);
//5.通信
char recvBuf[1024]={0};
//获取客户端的数据
while(1){
int num=read(cfd,recvBuf,sizeof(recvBuf));
if(num==-1){
perror("read");
exit(-1);
}else if(num>0){
printf("recv client data:%s\n",recvBuf);
}else if(num==0){
//表示客户端断开连接
printf("client closed...");
break;
}
char * data="hello,i am server";
//给客户端发送数据
write(cfd,data,strlen(data));
}
//关闭文件描述符
close(cfd);
close(lfd);
return 0;
}
客户端
#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
//1.创建套接字
int fd=socket(AF_INET,SOCK_STREAM,0);
if(fd==-1){
perror("socket");
exit(-1);
}
//2.连接服务器端
struct sockaddr_in serveraddr;
serveraddr.sin_family=AF_INET;
inet_pton(AF_INET,"192.168.227.129",&serveraddr.sin_addr.s_addr);
serveraddr.sin_port=htons(9999);
int ret=connect(fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret==-1){
perror("connect");
exit(-1);
}
char recvBuf[1024]={0};
//3.通信
while(1){
char * data="hello,i am client";
//给服务器发送数据
write(fd,data,strlen(data));
sleep(1);
int len=read(fd,recvBuf,sizeof(recvBuf));
if(len==-1){
perror("read");
exit(-1);
}else if(len>0){
printf("recv server data:%s\n",recvBuf);
}else if(len==0){
//表示客户端断开连接
printf("server closed...");
}
}
//关闭连接
close(fd);
return 0;
}
加上循环就是一直发送
TCP三次握手
三次握手发生在客户端连接的时候,在connect()函数调用时
滑动窗口
窗口理解为缓冲区的大小,滑动窗口的大小会随着发送数据和接收数据而变化。
通信的双方都有发送缓冲区和接收数据的缓冲区
TCP四次挥手
四次挥手发生在断开连接的时候,在程序中调用close()会使用TCP协议进行四次挥手。
客户端和服务器端都可以主动发起断开连接,和连接的时候不一样(客户端主动)
因为三次握手建立的连接是双向的,在断开的时候需要双向断开