服务器与客户端的一般套路

news2024/12/24 10:14:42

WinSocket 套接字

————服务器与客户端的一般套路

一、开发环境

  • IDE: Red Panda Dev-C++ 6.5
  • 编程语言:C语言
  • :winsock2.h

二、套接字工作流程图

img

注意:这个工作流程图非常重要,后面的代码编写基本就是这个逻辑

三、服务器各部分实现

  1. 导入头文件

    #include<stdio.h>
    #include<winsock2.h>	// 升级版头文件,现在一般都是用这个
    // #include<winsock.h>  // 原版头文件
    
  2. 初始化环境

    WSAStartup:在Windows平台上开发socket必写函数,用于允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节。只有调用了该函数window内核才知道你要使用的Socket API的版本号,所以一般都是放到代码之前,而且一般都是固定写法不需要改变。

    // 初始化 Socket环境 
    WSADATA WSAData;
    if(WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    	printf("初始化 Socket环境失败");
    	return -1;
    }
    	
    
  3. 创建套接字、绑定IP与端口,等待连接

    该步骤也基本是套路,只需要改下ip和端口就可以直接使用

    // 创建 Server 套接字
    SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == server) {
    	perror("创建 Server Socket失败!\n");
    	return -1;
    }
    
    // 创建并初始化服务器需要绑定IP和端口
    char IP[] = "127.0.0.1";
    int PORT = 8000;
    struct sockaddr_in server_addr;	// 服务器IP和端口信息
    server_addr.sin_family = AF_INET,	// 协议为网络协议
    server_addr.sin_port = htons(PORT),	// 绑定的端口
    // 绑定IP地址
    server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    // 服务器套接字绑定ip和端口
    int StatusCode = bind(server, (SOCKADDR*)&server_addr, sizeof(server_addr));
    if (SOCKET_ERROR == StatusCode) {
    	perror("Server Socket 绑定IP、端口失败\n");
    	return -1;
    }
    // 开始监听连接, 最多等待的连接数设置为10
    listen(server, 10);
    printf("Server 正在 %s %d 监听连接......\n", IP, PORT);
    
    
  4. 处理连接

    该部分基本也是套路,直接照搬

    // 接收客户端连接
    struct sockaddr_in client_addr;
    int client_addrlen = sizeof(client_addr);
    SOCKET client = accept(server, (SOCKADDR*)&client_addr, &client_addrlen);
    if (SOCKET_ERROR == client) {
    	perror("连接客户端失败\n");
    }
    
    
  5. 服务器与客户端交互

    该部分是交互部分,需要实现的具体功能就写到该部分,我这里的功能只是将客户端的数据原样返回

    // 处理客户端间的连接
    char buf[124] = {0};
    recv(client, buf, sizeof(buf), 0);	// 接收数据
    send(client, buf, sizeof(buf), 0);	// 发送数据
    
    
  6. 关闭连接

    // 关闭连接
    closesocket(client);
    closesocket(server);
    
  7. 释放套接字环境

    WSACleanup功能与WSAStartup功能相反

    // 释放资源
    WSACleanup();
    

如果在编译运行过程中报错,添加只需要在编译时添加上动态库(如下)

在这里插入图片描述

四、客户端各部分实现

  1. 导入头文件

    #include<stdio.h>
    #include<winsock2.h>	// 升级版头文件,现在一般都是用这个
    // #include<winsock.h>  // 原版头文件
    
    
  2. 初始化环境

    // 初始化 Socket环境 
    WSADATA WSAData;
    if(WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    	printf("初始化 Socket环境失败");
    	return -1;
    }
    
    
  3. 建立连接

    // 创建 Client 套接字
    SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == client) {
    	perror("创建 Client Socket失败!\n");
    	return -1;
    }
    
    // 创建并初始化代表服务器地址的IP和端口
    char IP[] = "127.0.0.1";
    int PORT = 8000;
    struct sockaddr_in server_addr;	// 服务器IP和端口信息
    server_addr.sin_family = AF_INET,	// 协议为网络协议
    server_addr.sin_port = htons(PORT),	// 绑定的端口
    // 绑定IP地址
    server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    // 连接上面服务器地址信息指定的服务器
    connect(client, (SOCKADDR*)&server_addr, sizeof(server_addr));
    
    
  4. 与服务器进行交互

    // 处理客户端间的连接
    char buf[124] = {0};
    send(client, buf, sizeof(buf), 0);	// 发送数据
    recv(client, buf, sizeof(buf), 0);	// 接收数据
    printf("Client 接收到的数据为:%s\n", buf);
    
  5. 断块连接、释放环境

    // 关闭连接并释放资源
    closesocket(client);
    WSACleanup();
    
    

五、运行结果与源码

  1. 服务器

    #include<stdio.h>
    #include<winsock2.h>
    
    int main () {
    	// 初始化 Socket环境
    	WSADATA WSAData;
    	if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    		perror("初始化 Socket环境失败\n");
    		return -1;
    	}
    
    	// 创建 Server 套接字
    	SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if (INVALID_SOCKET == server) {
    		perror("创建 Server Socket失败!\n");
    		return -1;
    	}
    
    	// 创建并初始化服务器需要绑定IP和端口
    	char IP[] = "127.0.0.1";	// 该ip代码的是本机地址
    	int PORT = 8000;
    	struct sockaddr_in server_addr;	// 服务器IP和端口信息
    	server_addr.sin_family = AF_INET,	// 协议为网络协议
    	server_addr.sin_port = htons(PORT),	// 绑定的端口
    	// 绑定IP地址
    	server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    	// 服务器套接字绑定ip和端口
    	int StatusCode = bind(server, (SOCKADDR*)&server_addr, sizeof(server_addr));
    	if (SOCKET_ERROR == StatusCode) {
    		perror("Server Socket 绑定IP、端口失败\n");
    		return -1;
    	}
    	// 开始监听连接, 最多等待的连接数设置为10
    	listen(server, 10);
    	printf("Server 正在 %s %d 监听连接......\n", IP, PORT);
    
    	// 接收客户端连接
    	struct sockaddr_in client_addr;
    	int client_addrlen = sizeof(client_addr);
    	SOCKET client = accept(server, (SOCKADDR*)&client_addr, &client_addrlen);
    	if (SOCKET_ERROR == client) {
    		perror("连接客户端失败\n");
    	}
    
    	// 处理客户端间的连接
    	char buf[124] = {0};
    	recv(client, buf, sizeof(buf), 0);	// 接收数据
    	send(client, buf, sizeof(buf), 0);	// 发送数据
    
    	// 关闭连接
    	closesocket(client);
    	closesocket(server);
    
    	// 释放资源
    	WSACleanup();
    	return 0;
    }
    
    
  2. 客户端

    #include<stdio.h>
    #include<winsock2.h>
    
    int main () {
    	// 初始化 Socket环境
    	WSADATA WSAData;
    	if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    		perror("初始化 Socket环境失败\n");
    		return -1;
    	}
    
    	// 创建 Client 套接字
    	SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if (INVALID_SOCKET == client) {
    		perror("创建 Client Socket失败!\n");
    		return -1;
    	}
    
    	// 创建并初始化代表服务器地址的IP和端口
    	char IP[] = "127.0.0.1";
    	int PORT = 8000;
    	struct sockaddr_in server_addr;	// 服务器IP和端口信息
    	server_addr.sin_family = AF_INET,	// 协议为网络协议
    	server_addr.sin_port = htons(PORT),	// 绑定的端口
    	// 绑定IP地址
    	server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    	// 连接上面服务器地址信息指定的服务器
    	connect(client, (SOCKADDR*)&server_addr, sizeof(server_addr));
    
    	// 处理客户端间的连接
    	char buf[124] = {0};
    	send(client, buf, sizeof(buf), 0);	// 发送数据
    	recv(client, buf, sizeof(buf), 0);	// 接收数据
    	printf("Client 接收到的数据为:%s\n", buf);
    	
    	// 关闭连接并释放资源
    	closesocket(client);
    	WSACleanup();
    	return 0;
    }
    
    
  3. 运行结果

    在这里插入图片描述
    在这里插入图片描述

WinSocket常用函数介绍:灰信网

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端基于DOM或者Canvas实现页面水印

&#x1f431; 个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff1a;vue3从入门…

AtCoder Beginner Contest 287(A~E)

比赛名称&#xff1a;UNIQUE VISION Programming Contest 2023 New Year (AtCoder Beginner Contest 287) 比赛链接&#xff1a;AtCoder Beginner Contest 287 目录 A - Majority B - Postal Card C - Path Graph? D - Match or Not E - Karuta A - Majority 问字…

工作和学习中都能用到的5款实用软件

如今&#xff0c;工作和学习都离不开电脑&#xff0c;所以电脑里的软件自然也是必不可少的&#xff0c;但是电脑软件那么多&#xff0c;不可能每个都装上吧&#xff0c;所以我们要装好用的、实用的&#xff0c;下面给大家分享5款好用到爆的软件&#xff0c;很多懂电脑的人都在用…

【算法】雪花算法

一.特点 1.全局唯一性&#xff1a;对于大数据量的分库分表场景&#xff0c;例如水平分表需要保证主键id的全局唯一性。 2.趋势递增&#xff1a;整体的id趋势是递增的&#xff0c;不是单调递增。 3.不规则性&#xff1a;id不连续&#xff0c;无规则&#xff0c;不规则。 4.包含…

乾元通多卡聚合通信设备保障生态环境监测网络

针对目前城市大气环境监测网格化建设&#xff0c;推出的新一代城市网格化大气环境监测系统&#xff0c;可以实现城市区域环境多维一体化监测管理&#xff0c;该设备主要用于监测大气环境中的PM10、TSP、PM2.5等颗粒物浓度&#xff0c;还可以实现环境监控&#xff0c;测噪音、大…

Node.JS 安装配置 | 安装排错解析

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Node.js下载 Node.js官方下载地址 官方下载如果慢&#xff0c;请用如下地址下载&#xff1a; Node.js 中文网 根据自己计算机配置下载 Next Next 安装地址可更换 Next…

年后找工作必看的自动化测试面试宝典,一般人我不告诉他

目录 前言 1.1 什么是 API&#xff1f; 1.2 什么是 API 测试&#xff1f; 1.3 常见的 API 测试类型有哪些&#xff1f; 1.4 列举 API 测试中使用的一些常用协议&#xff1f; 1.9API 常见测试有哪些&#xff1f; 1.10API 测试有哪些优势&#xff1f; 1.11API 测试中究竟…

【PHP 随记】—— Composer 安装项目以及项目的扩展

&#x1f449;总目录&#x1f448;\large\colorbox{skyblue}{&#x1f449;总目录&#x1f448;}&#x1f449;总目录&#x1f448;​ 文章目录1、Composer 安装项目① 项目安装示例② 相关问题解决③ 框架搜索指南2、Composer 安装项目的扩展使用 Composer 更轻松方便地安装 P…

RV1126笔记二十五:区域入侵检测

若该文为原创文章,转载请注明原文出处。 一、 前言 区域入侵检测是通过识别目标之后获取目标坐标位置,判断目标是否在所标定的区域内出现,常常被用在电子围栏,不安全区域入侵检测,智慧城市,安防监控等领域。具体使用场景有,在标定的区域内不能抽烟,进入工地区域必须佩…

Java快速上手Properties集合类

概念 Java中的Properties文件是一种配置文件&#xff0c;主要用于表达配置信息&#xff0c;格式是文本文件。该类主要用于读取Java的配置文件&#xff0c;也可以对properties文件进行修改 属性配置&#xff1a;以“键值”的方式书写一个属性的配置信息 注 释&#xff1a;在pro…

我建议大学生看一下阿凡达2,对离校后很有帮助

网上评价阿凡达2说剧情拉胯&#xff0c;但我却通过他的剧情看到了当代大学生的一些影子&#xff0c;尤其是对于离校的毕业生来说&#xff0c;相对吻合的场景还是很多的&#xff0c;让我来分析一下。 目录 阿发达2关键剧情点 1、在校期间 2、终于要离校了 3、离开学校&…

Flutter 安装踩坑记录 HTTP host https://pub.dev/ is not reachable.

Flutter安装踩坑记录安装Flutter SDK参考链接安装Flutter SDK Windows安装 flutter官网下载flutter sdk包 2.解压到C盘除去program file相关的目录&#xff08;最好自己创建一个新的目录&#xff0c;因为放在program file等目录需要特殊的权限&#xff0c;会出现问题&#xf…

【解读】CSA CISO研究报告: 零信任的部署现状及未来展望

零信任理念已经存在了十多年。然而对需要保护IT系统的企业来说&#xff0c;这个术语及其实施方式的关注度显著增加。 国际云安全联盟CSA发布调研报告《CISO研究报告&#xff1a;零信任的部署现状及未来展望》&#xff0c;本次调研的目的是使大家更好地理解组织机构内部的零信任…

【My Electronic Notes系列——放大电路与集成运算放大器】

目录 序言&#xff1a; &#x1f3c6;&#x1f3c6;人生在世&#xff0c;成功并非易事&#xff0c;他需要破茧而出的决心&#xff0c;他需要永不放弃的信念&#xff0c;他需要水滴石穿的坚持&#xff0c;他需要自强不息的勇气&#xff0c;他需要无畏无惧的凛然。要想成功&…

电脑怎么录制视频?如何录制页面上指定区域

你知道电脑怎么录制视频吗&#xff1f;有时候我们并不需要录制整个电脑屏幕&#xff0c;只需要对特定区域&#xff0c;这个时候该怎么办呢&#xff1f;其实我们只需要一款既支持全屏录制又支持区域录制的录屏工具&#xff0c;就可以轻松搞定。下面小编教您如何录制电脑上指定的…

azg携手Bubs出席2022未来母婴大会主题专场,探讨母婴品牌长红发展路径

近日&#xff0c;由母婴行业观察主办的“2022第八届未来母婴大会”在上海成功举办&#xff0c;来自行业内的近百位资深嘉宾受邀参与&#xff0c;共襄盛会。而在以“新周期 新机遇&#xff0c;母婴品牌可持续生长路径”的2022未来母婴大会主题专场中&#xff0c;Bubs中国区资深渠…

梦熊杯-十二月月赛-白银组题解-D.智慧

D. Problem D.智慧&#xff08;wisdom.cpp&#xff09; 内存限制&#xff1a;256 MiB 时间限制&#xff1a;1000 ms 标准输入输出 题目类型&#xff1a;传统 评测方式&#xff1a;文本比较 题目描述: 「须弥」是「智慧」的国度。 布耶尔认为&#xff0c;如果能只使用加…

CTFshow--web--红包题第七弹

好家伙&#xff0c;一打开就是个phpinfo&#xff0c;看看了感觉暂时没有什么利用的东西&#xff0c;扫一下目录吧使用dirsearch扫描&#xff0c;发现/.git/index的一个目录文件&#xff0c;访问下载他python dirsearch.py -u "http://98c1d213-ce9d-4415-99b1-2b4f2c80430…

java 探花交友项目day5 推荐好友列表 MongoDB集群 发布动态,查询动态 圈子功能

推荐好友列表 需求分析 推荐好友&#xff1a;分页形式查询推荐的用户列表&#xff0c;根据评分排序显示 代码实现&#xff1a; tanhuaController: /** * 查询分页推荐好友列表 */ GetMapping("/recommendation") public ResponseEntity recommendation(Recomme…

回归模型评价指标原理与基于sklearn的实现

1 前言 回归任务是机器学习中常见的任务&#xff0c;特别是涉及到具体的发电量预测、风力预测等工业任务时&#xff0c;有非常多的应用场景。回归任务不同于分类任务&#xff0c;回归任务的预测值一般是连续的数&#xff0c;分类任务的预测值则是离散的值&#xff08;比如0、1分…