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

思维导图:

使用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;
}
相关推荐
我好饿12 小时前
Linux入门教程 第十五章 Linux 系统调优工具
linux·运维·网络
2401_888423093 小时前
网络编程-TCP的并发服务器构建
服务器·网络·tcp/ip
bdgtd881788 小时前
动态修补C扩展模块的函数指针有哪些风险?安全的修补方案是什么?
c语言·开发语言·安全
bkspiderx8 小时前
安全扫描:目标主机支持RSA密钥交换问题
网络·nginx·安全·tls·rsa·弱算法
测试专家11 小时前
ARINC 825板卡的应用
大数据·网络·安全
二级小助手11 小时前
C语言二级考试环境配置教程【window篇】
c语言·全国计算机二级·c语言二级·二级c语言·全国计算机二级c语言·c二级
kyle~12 小时前
C/C++---前缀和(Prefix Sum)
c语言·c++·算法
lidashent12 小时前
c语言-内存管理
java·c语言·rpc
这里没有酒12 小时前
[C语言] 指针的种类
c语言
_OP_CHEN12 小时前
数据结构(C语言篇):(二)顺序表
c语言·数据结构·学习笔记·入门·顺序表·动态顺序表·静态顺序表