基于Select模型的通信仿真--win32编程代码

news/2024/11/18 18:22:10/文章来源:https://www.cnblogs.com/wa2211lq/p/18553351

目录
  • 基于Select模型的通信仿真--win32编程代码
    • 编程环境
    • 服务端
    • 客户端

基于Select模型的通信仿真--win32编程代码

编程环境

Visual C++ 6.0

服务端

#include<stdio.h>
#include<string.h>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR     lpCmdLine,int       nCmdShow)
{AllocConsole();freopen("CONOUT$","w",stdout);freopen("CONIN$", "r", stdin);freopen("CONOUT$", "w", stderr);// 初始化 WinsockWSADATA wsaData;int result=WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0) {printf("WSAStartup failed with error: %d\n", result);return 1;}//1.创建socket套接字/*SOCKET socket(_In_ int af,		//协议地址簇	IPv4:AF_INET/IPv6:AF_INET6_In_ int type,		//类型			流式协议:SOCK_STREAM/数据报协议:SOCK_DGRAM_In_ int protocol	//保护协议		上层协议tcp、udp不用写,填0即可);*/SOCKET listen_socket=socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET==listen_socket){printf("create listen socket failed!!! errcode: %d\n", GetLastError());WSACleanup();return -1;}//2.给socket绑定端口号/** ip地址结构体struct sockaddr_in {ADDRESS_FAMILY sin_family;	//协议地址簇USHORT sin_port;			//端口号	2字节IN_ADDR sin_addr;			//ip地址	4字节CHAR sin_zero[8];			//保留字节	8字节};struct sockaddr {u_short sa_family;					//协议地址簇CHAR sa_data[14];                   //14字节}*/struct sockaddr_in local = {0};local.sin_family = AF_INET;local.sin_port = htons(8080);//绑定端口 大小端转化:中间设备使用大端序(路由器),但是电脑使用的是小端序,所以要转化/*电脑上有多个网卡,服务器可以选择接收哪个或哪些网卡传过来的数据。如:127.0.0.1(本地环回),则服务器只能和自己通信	INADDR_LOOPBACK一般写全0地址(0.0.0.0),表示接收全部网卡的数据	INADDR_ANY*///local.sin_addr.s_addr = htonl(INADDR_ANY);//接收全部网卡的数据 大小端转化local.sin_addr.s_addr = inet_addr("0.0.0.0");//接收全部网卡的数据 字符串ip转成整数ip/*int bind(SOCKET s,							//绑定的套接字const struct sockaddr FAR * name,	//ip地址结构体int namelen							//ip地址结构体的长度);*/bind(listen_socket,(struct sockaddr*)&local,sizeof(local));//3.给socke开启监听属性,只用来接收连接/*int listen(_In_ SOCKET s,		//监听套接字_In_ int backlog	//);*/if (-1 == listen(listen_socket, 10)){printf("start listen failed!!! errcode: %d\n", GetLastError());WSACleanup();return -1;}fd_set redset;//4、初始化文件描述符集合  FD_ZERO(&redset);//5、添加要检测的监听文件描述符    FD_SET(listen_socket,&redset);printf("This is SERVER!\n");while (1){fd_set tmp = redset;/* 6、不停地检测文件描述符6.1 超时  select() = 0 再次检测或关闭套接字6.2 异常  select() = -1 异常处理6.3 成功  selct() >0*/printf("selecting...\n");int ret = select(-1, &tmp, NULL, NULL, NULL);if (ret <= 0){printf("select failed!!! errcode: %d\n", GetLastError());closesocket(listen_socket);WSACleanup();return -1;}// printf("select = %d\n",ret);//7、判断文件描述符属于哪一类//通过将原来redset集合中的文件描述符与select处理过的tmp集合比较,判断哪些文件描述符就绪,如果就绪,是哪一类for (int i = 0; i < (int)redset.fd_count; i++){if (FD_ISSET(redset.fd_array[i], &tmp))//判断文件描述符(套接字)i的读缓冲区是否有数据{//就绪文件描述符是监听描述符if (redset.fd_array[i] == listen_socket)    // 监听套接字接收到新连接{if (redset.fd_count < FD_SETSIZE){sockaddr_in addrRemote;int nAddrLen = sizeof(addrRemote);//接收客户端的连接请求SOCKET client_socket = ::accept(listen_socket, (SOCKADDR*)&addrRemote, &nAddrLen);FD_SET(client_socket, &redset);printf("与主机 %s 建立连接\n", inet_ntoa(addrRemote.sin_addr));}else{printf("Too much connections!\n");continue;}}else//就绪文件描述符不是监听描述符,是通信描述符{//接收信息char rbuffer[1024] = { 0 };int len = recv(redset.fd_array[i], rbuffer, 1024, 0);if (len <= 0){printf("The client %d has disconnected.\n", i);FD_CLR(redset.fd_array[i], &redset);shutdown(redset.fd_array[i], SD_BOTH);closesocket(redset.fd_array[i]);break;}printf("recive from client%d:\t%s\n", i, rbuffer);//发送信息char sbuffer[1024] = { 0 };// 检查接收到的消息if (strcmp(rbuffer, "计算从1到100的奇数和") == 0){int sum = 0;for (int j = 1; j <= 100; j += 2){sum += j;}printf("send to client%d:\t1到100的奇数和是 %d\n", i, sum);sprintf(sbuffer, "1到100的奇数和是 %d\n", sum);}else{printf("send to client%d:\tunknow!\n", i);sprintf(sbuffer, "unknow!");}len = send(redset.fd_array[i], sbuffer, strlen(sbuffer), 0);if (len == -1){perror("send error");exit(1);}}}}}closesocket(listen_socket);FreeConsole();// 清理 WinsockWSACleanup();return 0;
}

客户端

#include<stdio.h>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR     lpCmdLine,int       nCmdShow)
{AllocConsole();freopen("CONOUT$","w",stdout);freopen("CONIN$", "r", stdin);freopen("CONOUT$", "w", stderr);// 初始化 WinsockWSADATA wsaData;int result=WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0) {printf("WSAStartup failed with error: %d\n", result);return 1;}//1.创建socket套接字SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == client_socket){printf("create socket failed!!! errcode: %d\n", GetLastError());WSACleanup();return -1;}//2.连接服务器struct sockaddr_in target;//目标服务器的ip结构体target.sin_family = AF_INET;target.sin_port = htons(8080);target.sin_addr.s_addr = inet_addr("127.0.0.1");if (-1 == connect(client_socket, (struct sockaddr*)&target, sizeof(target))){printf("connect server failed!!!\n");shutdown(client_socket, SD_BOTH);closesocket(client_socket);WSACleanup();return -1;}//3.开始通讯printf("This is  Cilent1.\n\n");while (1){//发送信息printf("send:\t");char sbuffer[1024] = { 0 };scanf("%s", sbuffer);send(client_socket, sbuffer, strlen(sbuffer),0);//接收消息char rbuffer[1024] = { 0 };int ret=recv(client_socket, rbuffer, 1024, 0);if (ret <= 0){break;//断开连接}printf("recive:\t%s\n", rbuffer);}//4.关闭连接shutdown(client_socket, SD_BOTH);shutdown(client_socket, SD_BOTH);closesocket(client_socket);FreeConsole();// 清理 WinsockWSACleanup();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/836298.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验4 类的组合、继承、模板类、标准库

任务2 源码:1 #include <iostream>2 #include <vector>3 #include <string>4 #include <algorithm>5 #include <numeric>6 #include <iomanip>7 8 using std::vector;9 using std::string;10 using std::cin;11 using std::cout;12 using…

人工智能之机器学习线代基础——行列式、矩阵的 逆(inverse)、伴随矩阵

行列式(Determinant) 是线性代数中的一个重要概念,用于描述方阵的一些性质。行列式是一个标量,计算方法和矩阵的大小有关。 不使用代数余子式的定义 不使用代数余子式的定义的三阶计算案例 矩阵的 逆(inverse) 伴随矩阵

十光年团队——Alpha冲刺总结

目录1.项目冲刺链接2.项目完成情况(1)项目预期计划(2)现实进展(3)项目的亮点(4)项目的不足3.过程体会4.队员分工作业所属的课程 软件工程2024作业要求 2024秋软工实践团队作业-第三次( Alpha冲刺)作业的目标 团队分工,记录冲刺进度,对任务进行总结团队名称 十光年团…

银河护胃队-冲刺日志(第五天)

作业所属课程 https://edu.cnblogs.com/campus/fzu/SE2024/作业要求 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13305作业的目标 2024-11-15冲刺日志,记录每天的冲刺会议与进度团队名称 银河护胃队团队成员学号-名字 072208130-曹星才(组长)052205144-张诗悦1022…

数据采集作业4

数据采集作业四 gitee链接:https://gitee.com/wangzm7511/shu-ju/tree/master/作业4 1.使用 Selenium 爬取股票数据的实战 需求:熟练掌握 Selenium 查找 HTML 元素,爬取 Ajax 网页数据,等待 HTML 元素等内容。 使用 Selenium 框架 + MySQL 数据库存储技术路线爬取“沪深 A …

2.6

import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D 模拟高程数据(假设数据已经过某种方式插值或生成) 这里我们创建一个简单的40x50网格,并填充随机高程值 x = np.linspace(0, 43.65, 40) y = np.linspace(0, 58.2, 50) X, Y = …

2.1

import numpy as np import matplotlib.pyplot as plt 定义 x 的范围 x = np.linspace(-5, 5, 400) 计算三个函数的值 y_cosh = np.cosh(x) y_sinh = np.sinh(x) y_half_exp = 0.5 * np.exp(x) 创建图形和坐标轴 plt.figure(figsize=(10, 6)) ax = plt.gca() 绘制函数 ax.plot(…

2.2

import numpy as np import matplotlib.pyplot as plt from scipy.integrate import quad def fun(t, x): return np.exp(-t) * (t ** (x - 1)) x = np.linspace(0, 10, 100) # x 的范围 y = [quad(fun, 0, np.inf, args=i)[0] for i in x] # 计算积分 plt.plot(x, y) plt.xl…

Windows 右键新建文件添加指定后缀-bat批处理-c文件

前言全局说明一、说明 环境: Windows 7 旗舰版二、添加,创建 .bat 后缀文件 在命令行里执行下面两条命令 reg add HKCR\.bat\ShellNew /v nullfile /f >nul reg add HKCR\batfile /ve /d BAT批处理文件 /f >nul三、添加,创建 .c 后缀文件 reg add HKCR\.c\ShellNew /v …

数据结构(倒排索引)

倒排索引和正排索引倒排索引和正排索引 倒排索引是什么?倒排索引 也被称作反向索引(inverted index),是用于提高数据检索速度的一种数据结构,空间消耗比较大。倒排索引首先将检索文档进行分词得到多个词语/词条,然后将词语和文档 ID 建立关联,从而提高检索效率。分词就是…

旺仔水饺-冲刺日志 Day 6

作业所属课程 https://edu.cnblogs.com/campus/fzu/SE2024作业要求 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13305团队名称 旺仔水饺102201140 黎曼 102201138 黄俊瑶102201127 罗永辉 102201130 郑哲浩102202144 傅钰 102202147 赖越172209028 伊晓 052101418 陈…

服务器时间不对导致.NET SDK连接Minio失败

这两天想弄个简单的文件系统来做测试,选中了Minio,公司的测试环境是windows server2019,随手搜起一篇教程(MinIO注册成服务在后台运行(Win10)_minio windows 注册成服务在后台运行-CSDN博客),按图索骥,一顿操作猛如虎, 使用“WinSW”加入系统服务。打开网页一看,好使。…