客户端:向服务器发送连接请求给服务器发送数据,并且读取服务器端回写的数据。

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\n"); 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\n", 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\n",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\n"); close(sockfd); exit(1); } while (1) {
printf("input\n"); 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\n", buff); } close(sockfd);//客户端关闭 exit(0); }

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信