客户端服务器信息交互,select实现客户端和服务器端的信息交互(TCP socket)
实现功能:
客户端:<1>从标准输入(键盘)读入信息,然后通过socket发送到服务器端;
<2>接收来自服务器端的信息,并显示到终端里。
服务器端:<1>从标准输入(键盘)读入信息,然后通过socket发送到客户端;
<2>接收来自客户端的信息,并显示到终端里。
分析:
<1>首先需要建立服务器端与客户端之间通信的socket(本文采用TCP协议的socket);
<2>实现从标准输入读入、显示到终端;
<3>通过socket交互数据;
<4>交互数据时,由于编译器对代码的顺序执行,会造成阻塞(具体分析见下文)
实现细节:
<1>建立服务器端与客户端之间通信的socket(本文采用TCP协议的socket)
服务器端:
//定义server_sockfd
int server_sockfd =
socket(AF_INET,SOCK_STREAM, 0);
//定义sockaddr_in
(每一行的具体含义参考之前的文章推送)
struct sockaddr_in
server_sockaddr,client_addr;
socklen_t length =
sizeof(client_addr);
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(MYPORT); //8887
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//调用bind()函数,将上述地址结构和socket绑定在一起
bind(server_sockfd,(struct sockaddr
*)&server_sockaddr,sizeof(server_sockaddr));
//调用listen()函数,使套接字处于被动打开,监听状态
listen(server_sockfd,QUEUE);;
//当有来自客户端的连接请求(connect)时,调用accept()函数,至此完成TCP的三次握手
//注:conn是已连接套接字描述符、上面的server_sockfd是监听套接字描述符
int conn =
accept(server_sockfd, (struct sockaddr*)&client_addr,
&length);
客户端:
///定义sockfd
int sock_cli =
socket(AF_INET,SOCK_STREAM, 0);
///定义sockaddr_in
struct sockaddr_in
servaddr;
memset(&servaddr,
0, sizeof(servaddr));
servaddr.sin_family =
AF_INET;
servaddr.sin_port =
htons(MYPORT); ///服务器端口
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服务器ip
127.0.0.1:,本地回环地址、服务器在本机
///连接服务器
connect(sock_cli,
(struct sockaddr *)&servaddr, sizeof(servaddr)) ;
<2>实现从标准输入读入、显示到终端
从标准输入读入由函数fgets来实现,例如
fgets(sendbuf, sizeof(sendbuf), stdin);
显示到终端由函数fputs来实现,例如
fputs(recvbuf, stdout);
<3>通过socket交互数据
socket将收发数据封装在函数send和recv里,如下:
send(sock_cli, sendbuf,
strlen(sendbuf),0);
recv(sock_cli, recvbuf,
sizeof(recvbuf),0);
<4>交互数据时,由于编译器对代码的顺序执行,会造成阻塞(重点)
当客户端调用fgets函数以后,会阻塞于该函数,直到有键盘输入并且输入完成才返回。试想,如果此时从服务器端发来消息,由于客户端阻塞于fgets函数的调用,是不会去调用recv函数的,因此会忽略来自服务器的消息(该消息并没有被丢弃,而是保存在客户端的接收缓冲区)。
为了解决阻塞的问题,使得客户端或者服务器端能立即反映来自网络的消息以及来自标准输入的消息,不阻塞在任何一个函数,我们可以通过select函数来实现。
select函数允许进程指示内核等待多个事件中的任何一个发生,并且只在有一个或多个事件发生或经历一段指定长度的时间以后才唤醒它。(进程中,所有事件都是通过描述符来标识的,比如fgets的文件描述符、socket的已连接描述符等)
#include
#include
int select(int maxfdp1,fd_set *readset,
fd_set *writeset, fd_set *exceptset, const struct timeval
*timeout);
其中,maxfdp1是该select作用的所有描述符个数+1;参数readset、writeset、exceptset指定让内核测试读、写、异常的描述符;timeout则是指定一段时间,如果在这段时间内没有任何描述符打开,那么也会返回select的调用,上述参数除了maxfdp1必须指定,其余若不需要可直接置为NULL
服务器端以及客户端信息交互时select的应用:
fd_set rset;
FD_ZERO(&rset);
FD_SET(fileno(stdin),&rset);
FD_SET(sock_cli,&rset);
maxfdp1=5;
select(maxfdp1,&rset,NULL,NULL,NULL);
if(FD_ISSET(fileno(stdin),&rset)){
if(fgets(sendbuf,
sizeof(sendbuf), stdin) != NULL)
send(sock_cli, sendbuf,
strlen(sendbuf),0); ///发送
if(strcmp(sendbuf,"exit\n")==0) break;
memset(sendbuf, 0,
sizeof(sendbuf));
}
if(FD_ISSET(sock_cli,&rset)){
memset(recvbuf,0,sizeof(recvbuf));
int len =
recv(sock_cli, recvbuf, sizeof(recvbuf),0);
if(strcmp(recvbuf,"exit\n")==0) break;
fputs(recvbuf,
stdout);
}
客户端服务器信息交互,select实现客户端和服务器端的信息交互(TCP socket)相关推荐
- 服务器推送信息到客户端,服务器如何发送消息到客户端
服务器如何发送消息到客户端 内容精选 换一换 使用SSH方式登录CentOS 6.5操作系统的弹性云服务器时,过一段时间就会自动断开连接.本节操作介绍如何保持SSH会话持续连接不断开该文档适用于Cen ...
- ntp协议客户端服务器模式,思科配置NTP客户端服务器模式
思科配置NTP客户端服务器模式 内容精选 换一换 该操作指导安装工程师安装MRS集群所有服务(不包含Flume)的客户端.MRS针对不同服务提供了Shell脚本,供开发维护人员在不同场景下登录其对应的 ...
- 瘦客户端服务器系统,什么是瘦客户端管理系统
原标题:什么是瘦客户端管理系统 不知大家注意到没有,罗家这两年在其可视化解决方案中,多了一款名为 ThinManager (瘦客户端管理系统)的产品.那么,到底什么是瘦客户端管理系统?它与一般的可视化 ...
- 2-网络编程模型:认识客户端-服务器网络模型的基本概念
1.网络编程模型:认识客户端-服务器网络模型的基本概念 1.1.OSI模型和TCP/IP协议栈 1.2.客户端 - 服务器网络编程模型 网络购物来说,我们在手机上的每次操作,都是作为客户端向服务器发送 ...
- web与服务器之间的信息交互,web客户端与服务器端如何进行交互
web客户端与服务器端如何进行交互 内容精选 换一换 开启了 Kerberos认证的安全模式集群,进行应用开发时需要进行安全认证.Kerberos这一名词来源于希腊神话"三个头的狗--地狱之 ...
- 客户端与服务器信息交互的流程,客户端与服务器的交互流程
客户端与服务器的交互流程 内容精选 换一换 ecFlow是一个工作流管理器,使用户可以在受控环境中运行大量程序,彼此之间以及时间上相互依赖.它提供了对硬件和软件故障的容忍度,并具有良好的重启功能.ec ...
- 5G信令(就是用户身份信息)风暴——就是客户端通过公钥加密的消息(携带手机IMSI号)发给服务端,服务器需用私钥解密,这个解密比较消耗资源,如果短时间大量请求到来就会触发信令风暴...
信令:手机开机后,先从USIM中读取之前运营商分配的临时身份信息GUTI/TMSI,发送携带该身份信息的信令给基站,请求接入运营商网络. 如果每个设备的每条消息都需要单独认证,则网络侧安全信令的验证需 ...
- 恒大kk服务器信息端口,恒大kk手机客户端服务器
恒大kk手机客户端服务器 内容精选 换一换 用户启用应用备份前,需先在本地服务器或虚拟机上更改安全组和安装客户端.本章节指导用户下载并安装客户端.目前仅支持64位操作系统的主机,暂不支持32位操作系统 ...
- Redis获取客户端 服务器信息常用命令
AUTH password 通过设置配置文件中 requirepass 项的值(使用命令 CONFIG SET requirepass password ),可以使用密码来保护 Redis 服务器. ...
最新文章
- pymssql 安装后只有 .disk-info_变频空调安装注意事项
- I.MX6 Android i2c-tools porting
- Android Studio添加jar包
- nginx基本数据结构及接口
- wps 模拟分析 规划求解_【网友来稿】利用Excel求解线性规划问题
- C#的多线程机制探索3
- PAT: gets’ was not declared in this scope gets(s)
- GitHub 上数十个 NetBeans 开源项目被卷入供应链攻击
- Android解包命令:unpackbootimg与打包命令:mkbootimg使用
- php curl模拟post请求提交数据
- marlin固件烧录教程_marlin固件中文(marlin固件下载)【配置教程】
- idea文件夹代颜色代表的含义
- 腾讯云下centos git 克隆远程仓库
- 和平精英镜头灵敏度怎么调到最稳呢
- Pandas 01- Series
- oc代码混淆_oc代码混淆
- 苹果手机计算机怎么看之前的记录,苹果怎么查之前的通话记录吗(苹果手机怎么查通话录音内容)...
- 核算 央行 支付机构 备付金 对账10大文件等
- 【编译原理】-- 第一章(翻译程序、编译程序、汇编程序、解释程序、编译过程概述)
- 小说下载阅读器 官网
热门文章
- php curl 加载证书,php curl请求时,设置客户端证书及私钥
- js中将中国标准时间格式、CST日期转换为yyyy-MM-dd HH:mm:ss格式
- Adjtimex介绍
- 【Oracle相关】坑!使用oracle时,发生标识符无效解决办法
- Class ‘SoapClient‘ not found 解决方法
- 共享:程序员走上一条老路。
- 软件企业成长的烦恼――多个并行软件项目研发管理策略(1)--成长烦恼
- 计算机桌面造句四年级,桌面造句 - 用桌面造句大全(10-500个例子) - 第 2 页
- Oencv2 安装目录中 各个头文件的用途
- [计蒜客][dfs]中国象棋