华清远见作业第三十天——网络编程(第五天)

思维导图:

使用selsect实现TCP客户端的并发

代码

cpp 复制代码
#include<a.h>
#define SER_PORT  8888             //服务器端口号
#define SER_IP "192.168.125.50"    //服务器ip地址
#define CLI_PORT 6666                //客户端的端口号
#define CLI_IP "192.168.125.50"       //客户端ip地址


int main(int argc, const char *argv[])
{
	//1、创建用于通信的套接字文件描述符
    int cfd = -1;
    cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("cfd = %d\n", cfd);            //3

    //2、绑定(可选)
    //2.1 填充地址信息结构体 
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(CLI_PORT);
    cin.sin_addr.s_addr = inet_addr(CLI_IP);
    //2.2绑定
    if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
    {
        perror("bind error");
        return  -1;
    }
    printf("bind  success\n");
    
    //3、连接服务器
    //3.1 填充服务器地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family =     AF_INET;
    sin.sin_port =         htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);
    //3.2 连接
    if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("connect error");
        return -1;
    }
    printf("连接成功\n");
    //准备一个文件描述器
	fd_set readfds,tempfds;//临时集合
	//清空容器
	FD_ZERO(&readfds);
	//将要检测的文件放入集合中
	FD_SET(0,&readfds);
	FD_SET(cfd,&readfds);
	int res=-1; //接收select函数对容器的中文件描述符号检测的返回值


    //4、收发数据
    char wbuf[128]=""; //终端
	char rbuf[128]=""; //接收服务器发来的消息
    while(1)
    {
		tempfds=readfds; //存储一份数据
		//使用select函数对容器中的文件描述符进行检测
		res=select(cfd+1,&tempfds,NULL,NULL,NULL);
		if(res==-1)
		{
			perror("select error");
			return -1;
		}else if(res==0)
		{
			printf("timeout\n");
			return -1;
		}
		//判断终端是否发生事件
		if(FD_ISSET(0,&tempfds))
		{
		
		
			//清空数组
			bzero(wbuf, sizeof(wbuf));

			printf("请输入>>>");
			fgets(wbuf, sizeof(wbuf), stdin);   //从终端输入数据
			wbuf[strlen(wbuf)-1] = 0;          //将换行改为'\0'

			//发送给服务器
			send(cfd, wbuf, sizeof(wbuf), 0);
			printf("发送成功\n");
			if(strcmp(wbuf, "quit") == 0)
			{
				break;
			}
		}
		//判断是否是服务器发来的消息触发
		if(FD_ISSET(cfd,&tempfds))
		{
		
			//清空数组
			bzero(rbuf,sizeof(rbuf));
			//接收服务器发来的消息
			recv(cfd, rbuf, sizeof(rbuf), 0);
			printf("[%s:%d]:%s\n", SER_IP, SER_PORT, rbuf);
		}
    }

    //5、关闭套接字
    close(cfd);

    return 0;
}
相关推荐
wadesir1 小时前
C语言模块化设计入门指南(从零开始构建清晰可维护的C程序)
c语言·开发语言·算法
honsor1 小时前
精准监测 + 实时传输!网络型温湿度传感器,筑牢环境数据管理防线
网络·物联网
赖small强1 小时前
【Linux C/C++开发】 GCC -g 调试参数深度解析与最佳实践
linux·c语言·c++·gdb·-g
专家大圣2 小时前
远程调式不复杂!内网服务器调试用对工具很简单
运维·服务器·网络·内网穿透·cpolar
猫猫的小茶馆2 小时前
【ARM】ARM的介绍
c语言·开发语言·arm开发·stm32·单片机·嵌入式硬件·物联网
拾忆,想起3 小时前
Dubbo配置方式大全:七种配置任你选,轻松玩转微服务!
服务器·网络·网络协议·微服务·云原生·架构·dubbo
2501_941142933 小时前
云原生微服务环境下服务熔断与降级优化实践——提升系统稳定性与容错能力
java·大数据·网络
国科安芯4 小时前
航天医疗领域AS32S601芯片的性能分析与适配性探讨
大数据·网络·人工智能·单片机·嵌入式硬件·fpga开发·性能优化
zhurui_xiaozhuzaizai4 小时前
MoE模型的核心架构---专家网络---门控网络/路由器
网络·架构
普罗米修斯Aaron_Swartz5 小时前
云主机(容器)内实现本地VNC访问
网络·docker