TCP协议的客户端和服务器端通信
客户端:向服务器发送连接请求给服务器发送数据,并且读取服务器端回写的数据。
tcp协议特点:面向连接 可靠的 流式服务 应答确认超时重传
客户端和服务器端的通信通过套接字socket实现,套接字是两台主机之间通信的端点。
客户端和服务器端的通信由以下函数实现:
服务器端:
socket创建套接字
bind() 绑定 服务端用于将把用于通信的地址和端口绑定到 [socket]上
listen() 监听 设置最大的可连接的线路的数量
accept ()是一个阻塞函数(注:执行一该函数,则连接一次)
send recv()收发消息
close关闭
客户端:
socket创建套接字
connect() 发出连接请求
send recv 收发消息
close 关闭请求
服务器端代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建监听套接字
if ( sockfd == -1 )
{
exit(1);
}
struct sockaddr_in saddr,caddr;//tcp专用socket结构体
memset(&saddr,0,sizeof(saddr));
//初始化结构体
saddr.sin_family = AF_INET;//设定使用ipv4协议
saddr.sin_port = htons(6000);//端口号 1024知名端口 4096保留的端口 大于4096 临时端口 3306mysql端口号
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//服务器端地址
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//给套接字绑定端口号和地址 第二个参数需要把专用的强转为通用的
if ( res == -1 )
{
printf("bind err
");
close(sockfd);
exit(1);
}
res = listen(sockfd,5);//设置监听队列
if ( res == -1 )
{
close(sockfd);
exit(1);
}
while( 1 )
{
int len = sizeof(caddr);
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);//阻塞 c链接套接字 会有很多个c产生 只要有一个客户端连接上了就会产生一个c accept是唯一来判断客户端是否关闭的标志
if ( c == -1 )
{
continue;
}
printf("accept:%d
", c);
while(1)
{
char buff[128] = {0};
int n = recv(c,buff,127,0);//阻塞
if (n <= 0)// 客户端关闭时recv会发生阻塞 返回n=0 则退出这个循环 服务器端会关闭
{
break;
}
printf("recv(%d):%s
",c,buff);
send(c,"ok",2,0);
close(c);//客户端关闭时 停止收发 退出循环 服务器返回 accept处重新链接客户端
}
}
客户端代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if ( sockfd == -1 )
{
exit(1);
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);//htons主机转网络字节号 防止大小端
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//进行三次握手
if ( res == -1 )
{
printf("connect failed
");
close(sockfd);
exit(1);
}
while (1) {
printf("input
");
char buff[128] = { 0 };
fgets(buff, 128, stdin);
if (strncmp(buff, "end", 3) == 0)//输入end 跳出循环 关闭客户端
{
break;
}
send(sockfd, buff, strlen(buff) - 1, 0);
memset(buff, 0, 128);//清空 下一次重新输入;
recv(sockfd, buff, 127, 0);
printf("buff=%s
", buff);
}
close(sockfd);//客户端关闭
exit(0);
}
