网络编程 udp/ip协议 c/s模型

news2024/11/15 20:27:23

目录

1.概念​编辑

 2.代码解析

        1.recvfrom函数

        2.sendto函数

        3.内核泄露问题

整体代码


1.概念

 2.代码解析

        1.recvfrom函数

该函数接收数据报,并存储源地址,即得到当前服务器接收到的消息,并且存储在参数2,该函数是阻塞的,会一直死等,UDP是无差别获取客户端,是与客户端1对多的关系,函数原型

int WSAAPI recvfrom(
  [in]                SOCKET   s,
  [out]               char     *buf,
  [in]                int      len,
  [in]                int      flags,
  [out]               sockaddr *from,
  [in, out, optional] int      *fromlen
);

参数1:服务器socket

参数2:字符数组,用来存储收到的消息

参数3:想要读取的字节数

参数4:数据读取方式, 0表示默认方式

参数5:获取到对方的IP地址和端口号

参数6:参数5结构体大小

        返回值:成功放回字节数,失败返回SOCKET_ERROR

##代码样例

while (1)
	{
		struct sockaddr siClient;
		char strBuf[548] = { 0 };
		int nLen = sizeof(siClient);
		int num = recvfrom(socketServer, strBuf, nLen, 0, &siClient, &nLen);
		if (num == SOCKET_ERROR)
		{
			int a = WSAGetLastError();
			printf("接收出错,错误码:%d\n", a);
		}
	}

        2.sendto函数

该函数向目标发送数据,函数原型

int WSAAPI sendto(
  [in] SOCKET         s,
  [in] const char     *buf,
  [in] int            len,
  [in] int            flags,
  [in] const sockaddr *to,
  [in] int            tolen
);

参数1:服务器socket

参数2:要发送的字符串

参数3:发送的字符串的字节数

参数4:填0

参数5:对方IP地址和端口号

参数6:参数5的大小

        返回值:成功放回字节数,失败返回SOCKET_ERROR

##代码样例

//发送
		int sNum = sendto(socketServer, "hello Client", sizeof("hello Client"), 0, &siClient, sizeof(siClient));
		if (sNum == SOCKET_ERROR)
		{
			int a = WSAGetLastError();
			printf("发送出错,错误码:%d\n", a);
		}

        3.内核泄露问题

程序关闭是没有办法释放socket和网络库的,需要在主函数中投递一个监视函数,函数原型

主函数投递监视  SetConsoleCtrlHandler(HandlerRoutine,FALSE)
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
    switch(dwCtrlType)
    {
        case CTRL_CLOSE_EVENT:
            //释放socket
            break;
    }
    return FALSE;
}

##代码样例

BOOL WINAPI ctrlhandle(DWORD dwCtrlType)
{
	switch (dwCtrlType)
	{
	case CTRL_CLOSE_EVENT:
		closesocket(socketServer);
		WSACleanup();
		break;
	}
	return FALSE;
}

int main()
{
	SetConsoleCtrlHandler(ctrlhandle, TRUE);//投递监视函数
	//第一步 打开网络库并校验版本
}

整体代码

        服务器

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib, "ws2_32.lib")

SOCKET socketServer;

BOOL WINAPI ctrlhandle(DWORD dwCtrlType)
{
	switch (dwCtrlType)
	{
	case CTRL_CLOSE_EVENT:
		closesocket(socketServer);
		WSACleanup();
		break;
	}
	return FALSE;
}

int main()
{
	SetConsoleCtrlHandler(ctrlhandle, TRUE);//投递监视函数
	//第一步 打开网络库并校验版本
	WORD wdVersion = MAKEWORD(2, 2);
	WSADATA wdSockMsg;
	if (0 != WSAStartup(wdVersion, &wdSockMsg))
	{
		printf("打开网络库失败\n");
		return 0;
	}
	if (2 != HIBYTE(wdSockMsg.wVersion) || 2 != LOBYTE(wdSockMsg.wVersion))
	{
		printf("版本不对\n");
		WSACleanup();
		return 0;
	}
	//第二步 创建socket
	socketServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (socketServer == INVALID_SOCKET)
	{
		int a = WSAGetLastError();
		printf("socket创建失败\n");
		WSACleanup();
		return 0;
	}
	//第三步 绑定ip地址和端口号
	struct sockaddr_in si;
	si.sin_family = AF_INET;
	si.sin_port = htons(12345);
	si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	if (SOCKET_ERROR == bind(socketServer, (const SOCKADDR*)&si, sizeof(si)))
	{
		printf("绑定失败\n");
		closesocket(socketServer);
		WSACleanup();
		return 0;
	}
	//第四步 收发消息
	while (1)
	{
		//接收
		struct sockaddr siClient;
		char strBuf[548] = { 0 };
		int nLen = sizeof(siClient);
		int num = recvfrom(socketServer, strBuf, nLen, 0, &siClient, &nLen);
		if (num == SOCKET_ERROR)
		{
			int a = WSAGetLastError();
			printf("接收出错,错误码:%d\n", a);
		}

		printf("%s\n",strBuf);

		//发送
		memset(strBuf, 0, 548);
		scanf("%s", strBuf);
		int sNum = sendto(socketServer, strBuf, (int)strlen(strBuf), 0, &siClient, sizeof(siClient));
		if (sNum == SOCKET_ERROR)
		{
			int a = WSAGetLastError();
			printf("发送出错,错误码:%d\n", a);
		}
	}
	
	closesocket(socketServer);
	WSACleanup();

	return 0;
}

        客户端

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib, "ws2_32.lib")

int main()
{
	WORD wdVersion = MAKEWORD(2, 2);
	WSADATA wdSockMsg;
	if (0 != WSAStartup(wdVersion, &wdSockMsg))
	{
		printf("网络库打开失败\n");
		return 0;
	}
	if (2 != HIBYTE(wdSockMsg.wVersion) || 2 != LOBYTE(wdSockMsg.wVersion))
	{
		printf("版本不对\n");
		return 0;
	}
	SOCKET socketClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (socketClient == SOCKET_ERROR)
	{
		printf("创建socket失败\n");
		WSACleanup();
		return 0;
	}
	struct sockaddr_in siServer;
	siServer.sin_family = AF_INET;
	siServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	siServer.sin_port = htons(12345);

	while (1)
	{
		char strbuf[548] = { 0 };
		scanf("%s", strbuf);
		int sNum = sendto(socketClient, strbuf, (int)strlen(strbuf), 0, (const struct sockaddr*)&siServer, sizeof(siServer));
		if (sNum == SOCKET_ERROR)
		{
			printf("发送出错\n");
		}
		memset(strbuf, 0, 548);
		struct sockaddr siClient;
		int nLen = sizeof(siClient);
		int rNum = recvfrom(socketClient, strbuf, 548, 0, &siClient, &nLen);
		if (rNum == SOCKET_ERROR)
		{
			printf("接收出错\n");
		}
		printf("%s\n",strbuf);
	}

	return 0;
}

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

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

相关文章

c++构造和析构

1.构造函数 1.构造函数特性 构造函数名字和类名相同构造函数没有返回值(void有返回值&#xff0c;返回值为空)不写构造函数&#xff0c;每一个类中都存在默认的构造函数&#xff0c;默认的构造函数是没有参数的default显示使用默认的构造函数delete删掉默认函数当我们自己写了…

MM采购订单及发票相关后台表介绍(图解)

EKPO 采购凭证项目 EKKO 采购凭证抬头 EORD 采购货源清单 EINA 采购信息记录 - 一般数据 EINE 采购信息记录 - 采购组织数据 EKET 计划协议计划行 EKES 供应商确认 EKKN 采购凭证中的帐户设置 EKBE 采购凭证历史 EKBZ 每个采购凭证的历史&#xff1a;交货费用 RBKP 凭…

在wsl下开发T113的主线linux(2)-编译awboot

意外发现有awboot能够代替uboot直接引导内核&#xff0c;体验了一下果断选择awboot&#xff0c;因为足够简洁&#xff0c;编译大小只有32k&#xff0c;和uboot接近1M的体量相比&#xff0c;简直是小而美&#xff0c;启动速度也比uboot快上不少&#xff0c;也能同时支持sd卡&…

DoIP协议从入门到精通系列——车载网络拓扑

因特网协议(IP-Internet protocol)是互联网规范中的基本协议,它仅是支持互联网正常运转“TCP/IP”协议簇之一。UDP协议也是TCP/IP协议体系中的内容(因为名称中只含有TCP/IP名称,往往会忽略UDP)。以太网引入到车载网络后,汽车也会慢慢进入车联网时代(或者物联网,万物互…

aws codepipeline 在pipeline构建过程中使用变量

参考资料 Action structure reference codebuild构建环境中的环境变量 codepipeline中的变量 在codePipeline中使用变量 对于codepipeline来说&#xff0c;管道结构中的每个操作都有自身的结构和定义&#xff0c;本文主要讨论不同资源的输出变量。 基本概念 变量允许用户…

数据完整性(一)

目录 数据完整性&#xff1a; 什么是数据完整性&#xff1a; 数据完整性的类型 1&#xff1a;实体完整性 2&#xff1a;域完整性&#xff1a; 3、引用完整性&#xff1a; 4、自定义完整性&#xff1a; 完整性约束&#xff1a; 数据完整性的实现方式&#xff1a; 实体完整性&a…

抽象⼯⼚模式

抽象⼯⼚模式 1.抽象工厂模式介绍 抽象⼯⼚模式与⼯⼚⽅法模式虽然主要意图都是为了解决&#xff0c;接⼝选择问题。但在实现上&#xff0c;抽象⼯⼚是⼀ 个中⼼⼯⼚&#xff0c;创建其他⼯⼚的模式。 2.案例场景模拟 2.1场景简述 很多时候初期业务的蛮荒发展&#xff0c;也…

NLP中隐性语义分析及奇异值分解(SVD)-学习笔记

目录 1、隐性语义分析 2、奇异值分解 2.1 左奇异向量U 2.2 奇异值向量S 2.3 右奇异值向量V^T 2.4 SVD矩阵的方向 2.5 主题约简 1、隐性语义分析 隐形语义分析基于最古老和最常用的降维技术–奇异值分解(SVD)。SVD将一个矩阵分解成3个方阵&#xff0c;其中一个是对角矩阵…

网络类型实验报告

实验拓扑 实验要求 1.R2为ISP&#xff0c;其上只能配置IP地址 2.R1-R2之间为HDLC封装 3.R2-R3之间为ppp封装&#xff0c;pap认证&#xff0c;R2为主认证方 4.R2-R4之间为PPP封装&#xff0c;chap认证&#xff0c;R2为主认证方 5.R1、R2、R3构建MGRE环境&#xff0c;仅R1P地址固…

【C++】-- C++11基础常用知识点

目录 C11简介 统一的列表初始化 &#xff5b;&#xff5d;初始化 std::initializer_list std::initializer_list使用场景&#xff1a; 声明 auto decltype nullptr 范围for循环 STL中一些变化 新容器 array容器 forward_list容器 容器中的一些新方法 C11简介 在…

TDK | RoboKit1-DK 开发平台为实现未来机器人的多样性扫清障碍

机器人行业正在飞速发展&#xff0c;新技术亦层出不穷。TDK 现推出了 TDK RoboKit1-DK 机器人开发平台&#xff0c;该平台配备了机器人精确操作所必需的各种传感器&#xff0c;有助于在各种机器人开发中提高效率和性能。 在技术快速进步与成长的环境中&#xff0c;机器人开发所…

计算机组成原理实验——二、寄存器实验

一、实验目的 1.掌握寄存器堆的工作原理和接口。 2.掌握寄存器堆的实现方法。 3.掌握寄存器堆在微处理器中承担的功能。 二&#xff0e;实验内容 设计一32*32bit 的寄存器文件&#xff0c;即32 个 32 位的寄存器文件&#xff08;寄存器组&#xff09; –具备两组读端口及一组…

【王道操作系统】2.2.1 处理机调度的概念与层次

处理机调度的概念与层次 文章目录处理机调度的概念与层次1.调度的基本概念2.调度的三个层次2.1 高级调度(作业调度)2.2 中级调度(内存调度)2.3 进程的挂起状态与七状态模型2.4 低级调度(进程调度)2.5 三层调度的联系和对比1.调度的基本概念 2.调度的三个层次 2.1 高级调度(作业…

GroundTrue和里程计输出的位姿的参考坐标系不一致的情况

这里写目录标题前言数据集描述使用TF工具包获取使用Eigen库计算置换输出误差对比没做转换之前转换之后前言 最近遇到一个数据集的ground true参考坐标和vSLAM输出的位姿的参考坐标不一样的问题&#xff0c;记录一下。 在之前参加的一个PRCV 2022的多传感器融合SLAM挑战赛中也同…

MATLAB读取tif格式图像

tif格式数据本质上就是带有地理信息的矩阵数据。 geotiffread函数 MATLAB帮助-geotiffread 语法Syntax&#xff1a; [A,R] geotiffread(filename) [X,cmap,R] geotiffread(filename) [A,refmat,bbox] geotiffread(filename) [X,cmap,refmat,bbox] geotiffread(filenam…

Symbol详解

Symbol Symbol是es6引入的一个新的原始数据类型&#xff0c;是一个独一无二的值。 目前为止&#xff0c;js的数据类型有以下几种&#xff1a; 数据类型说明undefinedundefinednullnullboolean布尔值string字符串number数字Bigint大整数Object对象SymbolSymbol Symbol通过Symb…

[go学习笔记.第十八章.数据结构] 2.约瑟夫问题,排序,栈,递归,哈希表,二叉树的三种遍历方式

一.约瑟夫问题 josephu 问题: 设编号为1, 2 &#xff0c;... n 的n个人围坐一圈, 约定编号为 k (1<k<n &#xff09;的人从 1 开始报数&#xff0c;数到m的那个人出列&#xff0c;它的下一位又从1开始报数&#xff0c;数到 m 的那个人又出列&#xff0c;依次类推&#xf…

ActivityManagerService

1 AMS 家族 ActivityManagerService&#xff08;AMS&#xff09;主要负责系统中四大组件的启动、切换、调度以及应用程序的管理和调度工作&#xff0c;其职责与操作系统中的进程管理和调度模块类似。ActivityManagerService 进行初始化的时机很明确&#xff0c;就是在 system_…

计算机组成原理“上分秘籍”——数据的表示和运算

前言 上分地图 目录 前言 上分地图 猜你想问 Q1&#xff1a;为何要研究数据表示问题&#xff1f; Q2&#xff1a;什么叫数据表示&#xff1f;计算机中又有哪些方法&#xff1f; 正文 上分突破口1&#xff1a;进位计数法 例&#xff1a;二进制转为十进制 例&#xff…

路由综合实验

目录需求分析解决方法1&#xff0c;环回配置2&#xff0c;路由接口ip配置3&#xff0c;配置DHCP服务4&#xff0c;配置缺省5&#xff0c;静态路由配置6.浮动路由配置7&#xff0c;nat的配置8&#xff0c;远程服务及端口进行映射需求分析 一&#xff0c;原始需求如图&#xff1…