客户端服务器信息交互,select实现客户端和服务器端的信息交互(TCP socket)

2023-05-16

实现功能:

客户端:<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);

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

客户端服务器信息交互,select实现客户端和服务器端的信息交互(TCP socket) 的相关文章

随机推荐

  • 多线程的优缺点

    何时使用多线程技术 何时避免用它 是我们需要掌握的重要课题 多线程技术是一把双刃剑 在使用时需要充分考虑它的优缺点 多线程处理可以同时运行多个线程 由于多线程应用程序将程序划分成多个独立的任务 因此可以在以下方面显著提高性能 1 多线程技术
  • 单片机应用编程技巧问答

    1 C语言和汇编语言在开发单片机时各有哪些优缺点 答 xff1a 汇编语言是一种用文字助记符来表示机器指令的符号语言 xff0c 是最接近机器码的一种语言 其主要优点是占用资源少 程序执行效率高 但是不同的CPU xff0c 其汇编语言可能
  • php获取今日开始时间戳和结束时间戳

    1 php获取今日开始时间戳和结束时间戳 beginToday 61 mktime 0 0 0 date 39 m 39 date 39 d 39 date 39 Y 39 endToday 61 mktime 0 0 0 date 39
  • BDA驱动学习笔记(1):功能拓扑图

    功能拓扑图 Functional Topology xff1a BAD的目标是不管硬件或者接收信号如何变 xff0c 它的整体架构可以不做大调整 xff0c 为此BDA引入功能拓扑图的概念 xff0c 它把类似DirectShow Filt
  • linux 流量监控利器:iftop

    在类Unix系统中可以使用top查看系统资源 进程 内存占用等信息 查看网络状态可以使用netstat nmap等工具 若要查看实时的网络流量 xff0c 监控TCP IP连接等 xff0c 则可以使用iftop iftop是什么 ifto
  • VS Code C++ 代码格式化方法(clang-format)

    前提条件 安装扩展C C 43 43 xff0c 扩展程序将自动安装clang format clang format默认安装路径为c Users wqr57 vscode extensions ms vscode cpptools 0 1
  • 为ubuntu服务器安装gnome图形桌面

    一般租用的服务器安装服务器版的LINUX xff0c 很少会安装桌面的 xff0c 主要是觉得浪费资源吧 xff0c 不过我这样的菜鸟还是喜欢图形桌面 xff0c 下面主要记录下这次为ubuntu 11 04版本安装GNOME xff0c
  • js表单验证 方法

    1 长度限制 lt p gt 1 长度限制 lt p gt lt form name 61 a nsubmit 61 34 return test 34 gt lt textarea name 61 34 b 34 cols 61 34 4
  • 海量数据处理之倒排索引

    前言 xff1a 本文是对博文http blog csdn net v july v article details 7085669的总结和引用 一 xff0c 什么是倒排索引 问题描述 xff1a 文档检索系统 xff0c 查询那些文件包
  • linux 服务器杀毒,一次Linux服务器***查杀经历

    1客户自己的服务器由于种了 xff0c 往外发送大量数据包 xff0c 被服务商切断网络 虽然没有网络不能直接登录服务器 xff0c 但是可以通过服务商提供的WEB控制面板进入操作系统 首先使用命令查看相关连接 xff1a netstat
  • 问题请教:关于同一个POD中多容器的广播信息问题

    广大博友好 xff0c 最近在K8S集群中遇到一个问题 xff0c 贴出来同大家分享一下 同一个POD中多个容器 如何处理广播信息 xff1f 经测试 同一个POD中当先启动的容器占用广播端口后 xff0c 其他的容器启动就会报bind e
  • JAVA在线观看视频教程完整版

    今天给大家介绍一下JAVA在线观看视频教程完整版 xff0c 我们知道Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言 xff0c 是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台
  • Dockerfile镜像的制作

    Dockerfile镜像的制作 如果学习Docker xff0c 那么制作镜像这一步肯定不能少的 xff0c 别人给你的是环境 xff0c 而你自己做的才是你最终需要的东西 xff0c 接下来就记录一下如何制作一个满足自己的镜像 xff0c
  • OpenWRT 编译教程

    1 安装Ubuntu 到 http www ubuntu org cn desktop get ubuntu download 下载 xff0c 版本随便 xff0c 我选的是10 10 32位版 安装过程就不说了 xff0c 图形化安装
  • 树莓派VNC搭建相关教程+Ubuntu16.04连接vncserver灰屏问题!

    树莓派VNC搭建相关教程 xff1a 为了节省money xff0c 于是我决定用VNC界面来代替显示器 xff0c 为后面做C 43 43 Qt以及Python Qt开发打下基础 xff0c 我别无选择 xff01 下面开始进入正题 xf
  • linux中wait系统调用

    系统中的僵尸进程都要由wait系统调用来回收 xff0c 下面就通过实战看一看wait的具体用法 xff1a wait的函数原型是 xff1a include lt sys types h gt 提供类型pid t的定义 include l
  • go 使用channel交叉打印奇偶数

    方法1 使用两个协程一个管道 xff0c 一个协程输入 xff0c 另一个协程接收 xff0c 保证i在两个协程中的值一样 package main import 34 fmt 34 34 sync 34 var wg sync WaitG
  • 事件冒泡机制和事件委派 以及回调的匿名函数参数

    1 事件冒泡机制 xff1a 事件冒泡机制也就是当一个事件绑定到一个元素上时 xff0c 如果这个元素不存在或者回调函数返回ture 那么这个事件就会向上冒泡 xff0c 继续绑定这个元素的父级元素直至document xff08 如果事件
  • Linux 内核硬件抽象

    我们结束 PCI 的讨论 通过快速看一下系统如何处理在市场上的多种 PCI 控制器 这只 是一个信息性的小节 打算来展示给好奇的读者 内核的面向对象分布如何向下扩展到最 低层 用来实现硬件抽象的机制是通常的包含方法的结构 它是一个很强功能的
  • 客户端服务器信息交互,select实现客户端和服务器端的信息交互(TCP socket)

    实现功能 xff1a 客户端 xff1a lt 1 gt 从标准输入 键盘 读入信息 xff0c 然后通过socket发送到服务器端 lt 2 gt 接收来自服务器端的信息 xff0c 并显示到终端里 服务器端 xff1a lt 1 gt