Day2:Windows网络编程-TCP

news2024/11/27 10:31:47

今天开始进入Windows网络编程的学习,在学习的时候总是陷入Windows复杂的参数,纠结于这些。从老师的讲解中,这些内容属于是定式,主要学习写的逻辑。给自己提个醒,要把精力放在正确的位置,不要无端耗费精力。

关于C/S模式

C:Client 客户端:

  • 打开一个通信通道,并连接到服务器所在主机的特定端口
  • 向服务器发服务请求,等待并接收应答,继续提出请求
  • 请求结束后关闭通信通道并终止

S:Server 服务端:

  • 首先服务器先启动,并根据请求提供相应的服务
  • 打开一个通信通道,在某一地址和端口上接收请求
  • 等待客户请求到达该端口
  • 接收到服务请求,处理该请求并发送应答信号
  • 返回第二步,等待另一客户请求
  • 关闭服务器

关于TCP与UDP

TCP:面向连接的套接字

  • 传输过程中数据不会丢失
  • 按顺序传输数据
  • 传输的过程中不存在数据边界

UDP:面向消息的套接字

  • 强调快速传输而非顺序
  • 传输的数据可能丢失也可能损毁
  • 限制每次传输数据的大小
  • 传输的数据由数据边界

关于IP

是分配给用户上网使用的网际协议

常见的IP地址分为IPv4与IPv6两大类两大类

关于端口

为区分程序中创建的套接字而分配给套接字的序号

不同的端口对应不同的应用程序

端口有65536之多

关于套接字类型与协议设置

SOCK_STREAM 对应TCP协议

SOCK_DGRAM 对应UDP

SOCK_RAW 可以读写内核没有处理的IP数据包,避开 TCP/IP 处理机制,被传送的数据报可以被直接传送给需要它的的应用程序

关于网络编程的基本函数和基本数据结构

两个重要的数据结构:

struct sockaddr {
    u_short sa_family; //16 位地址类型 2 字节
    char sa_data[14]; //14 字节地址数据:ip + port
};
struct sockaddr_in {
    short sin_family; //16 位地址类型
    u_short sin_port; //16 位端口号 65535 2 的 16 次方
    struct in_addr sin_addr; //32 位 IP 地址 4 字节
    char sin_zero[8]; //8 字节填充
};

TCP 套接字

 

TCP Server

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>

// error LNK2019: 无法解析的外部符号 __imp__accept@12,函数 _main 中引用了该符号
#pragma comment(lib,"ws2_32.lib")   // 导入库

int main()
{
	printf("TCP Server\n");
	// 0. 初始化网络库 加载套接字库 这是个标准做法,直接拷贝即可
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 2);
	// 1、初始化套接字库
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		printf("WSAStartup errorNum = %d\n", GetLastError());
		return err;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		printf("LOBYTE errorNum = %d\n", GetLastError());
		WSACleanup();
		return -1;
	}

	// 1. 安装电话机
	// AF_INET指定了使用 IPv4 地址和 TCP/IP 协议栈进行网络通信。
	// 用于指定套接字的类型,表示基于流的传输协议,常用于 TCP 协议的网络通信。
	// 第三个参数由前两个决定。
	// 光标放在socket()函数上,摁下F1,转到官方文档
	SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);   //socket 函数创建一个绑定到特定传输服务提供者的套接字。
	if (INVALID_SOCKET == sockSrv)
	{
		printf("socket errorNum = %d\n", GetLastError());
		return -1;
	}
	
	// 2. 分配电话号码,填充参数
	SOCKADDR_IN addSrv;  // SOCKADDR_IN结构指定 AF_INET 地址系列的传输地址和端口。
	// 设置为任何IP
	addSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addSrv.sin_family = AF_INET;
	addSrv.sin_port = htons(6000);
	// 根据官方文档,这里需要强转 
	if (SOCKET_ERROR == bind(sockSrv, (SOCKADDR*)&addSrv, sizeof(SOCKADDR))) // 绑定函数将本地地址与套接字相关联。
	{
		printf("bind errorNum = %d\n", GetLastError());
		return -1;
	}
	
	// 3. 监听 listen
	// 将套接字置于侦听传入连接的状态。
	if (SOCKET_ERROR == listen(sockSrv, 5))
	{
		printf("listen errorNum = %d\n", GetLastError());
		return -1;
	}

	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);
	while (true)
	{
		// 4.分配一台分机去处理客户端的连接
		printf("begin accept: \n");
		SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrCli,&len);
		printf("end accept: \n");
		char sendBuf[100] = { 0 };
		sprintf_s(sendBuf, 100, "Welcome %s to bingo!",inet_ntoa(addrCli.sin_addr));
		int iLen = send(sockConn,sendBuf,strlen(sendBuf),0);
		char recvBuf[100] = { 0 };
		iLen = recv(sockConn, recvBuf, 100, 0);
		printf("recvBuf = %s\n", recvBuf);
		// 关闭分机
		closesocket(sockConn);
	}
	// 关闭总机
	closesocket(sockSrv);
	WSACleanup();
	system("pause");
	return 0;
}

TCP Client

代码如下:

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

int main()
{
	printf("Client\n");
	char sendBuf[] = "hello,world";
	//1 初始化网络库
	// 加载套接字库
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 2);
	// 1、初始化套接字库
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		printf("WSAStartup errorNum = %d\n", GetLastError());
		return err;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		printf("LOBYTE errorNum = %d\n", GetLastError());
		WSACleanup();
		return -1;
	}
	// 2 安装电话机
	// 新建套接字
	SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == sockCli)
	{
		printf("socket errorNum = %d\n", GetLastError());
		return -1;
	}
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("10.134.142.81");
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	// 3 连接服务器
	if (SOCKET_ERROR == connect(sockCli, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)))
	{
		printf("connect errorNum = %d\n", GetLastError());
		return -1;
	}
	// 4 接收和发送数据
	char recvBuf[100] = { 0 };
	int iLen = recv(sockCli, recvBuf, 100, 0);
	if (iLen < 0)
	{
		printf("recv errorNum = %d\n", GetLastError());
		return -1;
	}
	printf("Client recvBuf = %s\n", recvBuf);
	// 发送数据
	iLen = send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);
	if (iLen < 0)
	{
		printf("send errorNum = %d\n", GetLastError());
		return -1;
	}
	// 关闭套接字
	closesocket(sockCli);
	WSACleanup();
	system("pause");
	return 0;
}

// 报错:严重性	代码	说明	项目	文件	行	禁止显示状态
// 错误	C4996	'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings	TCP Client	C : \Users\mi\Desktop\Code - C++\MyNetPro\TCP Client\TCP Client.cpp	38
// 我们需要把它 _WINSOCK_DEPRECATED 忽略掉 工程属性 C++预处理器添加即可

结果如下:

关于Listen()

listen(sockSrv,5):这个函数是规定了消息队列,最多可以有五个,后面再来的消息会来连接不上。

关于VS的启动项

设置哪个为启动项就会编译那个过程的C++文件

 

关于报错: _WINSOCK_DEPRECATED 

// 报错:严重性    代码    说明    项目    文件    行    禁止显示状态
// 错误    C4996    'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings    TCP Client    C : \Users\mi\Desktop\Code - C++\MyNetPro\TCP Client\TCP Client.cpp    38
// 我们需要把它 _WINSOCK_DEPRECATED 忽略掉 工程属性 C++预处理器添加即可

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

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

相关文章

【JavaScript】文件分片上传

文章目录 普通文件上传分片上传整体流程技术点分析文件选择方式隐藏input框&#xff0c;自定义trigger拖拽上传 分片动态分片 计算哈希workerrequestIdleCallback抽样 请求并发控制进度展示手动中止/暂停 合并流式并发合并 反思分片命名问题并发控制代码实现的问题 参考文献 普…

ChatGPT桌面客户端支持gpt4模型,附使用说明

#软件核心功能&#xff1a; 1、支持OpenAI官方秘钥及API2D双秘钥使用&#xff1b;如果全局魔法&#xff0c;可以自己用官方秘钥&#xff1b;没魔法国内可直接使用API2D秘钥&#xff1b; 2、内置GPT4模型选项&#xff0c;如果你的官方秘钥支持可直接使用&#xff1b;你也可以注册…

【Labview如何显示数据库表格中的内容】

Labview如何显示数据库表格中的内容 前提操作思路框图 前提 已经成功将数据库与Labview相连接&#xff0c;若还没有链接可以查看&#xff1a;Labview与SQL Server互联 进行操作 操作 思路 首先创建一个表格控件&#xff0c;通过一个按钮启动程序&#xff0c;通过程序调用数…

SAP MM 根据采购订单反查采购申请

如何通过采购订单号查询到其前端的采购申请号。 首先从采购申请的相关报表着手&#xff0c;比如ME5A, 发现它是可以满足需求的。 例如&#xff1a;如下的采购订单&#xff0c; 该订单是由采购申请10003364转过来的。 如果想通过这个采购订单找到对应的采购申请&#xff0c;在…

Packet Tracer – 配置命名标准 IPv4 ACL

Packet Tracer – 配置命名标准 IPv4 ACL 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 R1 F0/0 192.168.10.1 255.255.255.0 N/A F0/1 192.168.20.1 255.255.255.0 N/A E0/0/0 192.168.100.1 255.255.255.0 N/A E0/0/1 192.168.200.1 255.255.2…

第五十五天学习记录:C语言进阶:动态内存管理Ⅲ

柔性数组 C99中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做柔性数组成员。 柔性数组的特点&#xff1a; 。结构体中的柔性数组成员前面必须至少有一个其他成员。 。sizeof返回的这种结构大小不包括柔性数组的内存。 。包含柔性数组成员的结构…

【C++学习】智能指针

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 智能指针 &#x1f96e;智能指针&#x1f362;为什么需要智能指针&#x1f362;RAII &#x1f96e;au…

chatgpt赋能python:Python自动开机:提高效率的必备工具

Python 自动开机&#xff1a;提高效率的必备工具 随着科技的发展&#xff0c;计算机在我们的日常生活中扮演了越来越重要的角色。为了提高工作效率和使用体验&#xff0c;越来越多的人开始探索利用自动化工具来简化日常操作。 Python 称得上是自动化领域中的一把利器。通过代…

SAP-MM费用类采购通过物料组确定科目

一、WRX的配置&#xff0c;分两类GR/IR科目&#xff1a; 1、做库存管理物料的GR/IR科目&#xff0c;需要配置评估类&#xff0c;此评估类就是物料主数据里配置的评估类&#xff1b; 2、非库存管理费用化物料的GR/IR科目&#xff0c;如固定资产、办公用品、低值易耗品等等&#…

chatgpt赋能python:Python生成C代码:如何用Python快速高效地生成C代码

Python生成C代码&#xff1a;如何用Python快速高效地生成C代码 在现代编程中&#xff0c;有许多原因需要编写C代码。C是一种高性能语言&#xff0c;它允许程序员直接操作计算机的硬件。但是&#xff0c;编写C代码需要花费大量的时间和精力。幸运的是&#xff0c;Python可以帮助…

Spring Boot问题汇总

1.IDEA里yaml文件编辑时没有提示 网上很多教程说在设置里的File Types里把yaml格式加入到关联中 但其实我打开IDEA默认就是这么设置的&#xff0c;所以并没有什么用处。 不过在翻看这篇教程&#xff08;IDEA创建yml文件不显示小树叶创建失败问题的解决方法-eolink官网&#x…

网络安全学习心得分享~

我的学习心得&#xff0c;我认为能不能自学成功的要素有两点。 第一点就是自身的问题&#xff0c;虽然想要转行学习安全的人很多&#xff0c;但是非常强烈的想要转行学好的人是小部分。而大部分人只是抱着试试的心态来学习安全&#xff0c;这是完全不可能的。 所以能不能学成并…

【Python】字符串操作

知识目录 一、写在前面✨二、字符串逆序三、打印菱形四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是初心&#xff0c;很高兴再次跟大家见面。&#xff08;相遇就是缘分啊&#xff09; 今天跟大家分享的文章是 Python中的字符串操作 &#xff0c;希望能帮助…

SAP-物料主数据-质量管理视图字段解析

过账到质检库存&#xff1a;要勾选&#xff0c;否则收货后库存不进入质检库存HU检验&#xff1a;收货到启用HU管理的库位时产生检验批&#xff0c;例如某个成品物料是收货到C002库位&#xff0c;该库位启用了HU管理&#xff0c;那么此处要勾选。但是如果勾选了&#xff0c;却收…

全网最全最有用的网络安全学习路线!整整一晚上才整理出来!

正文&#xff1a; 废话不多说&#xff0c;先上一张图镇楼&#xff0c;看看网络安全有哪些方向&#xff0c;它们之间有什么关系和区别&#xff0c;各自需要学习哪些东西。 在这个圈子技术门类中&#xff0c;工作岗位主要有以下三个方向&#xff1a; 安全研发安全研究&#xff1…

Linux-0.11 文件系统pipe.c详解

Linux-0.11 文件系统pipe.c详解 模块简介 在Linux-0.11中提供了管道这种进程间通讯的方式。本程序包含了管道文件读写操作函数read_pipe()和write_pipe()。 函数详解 read_pipe int read_pipe(struct m_inode * inode, char * buf, int count)该函数是读管道的方法。 函数…

python绘图工具matpoltlib的常用操作

目录 1.matplotlib概述2.风格设置3.条形图4.盒图5.直方图和散点图6.3D图7.pie图和布局8.Pandas与sklearn结合实例 1.matplotlib概述 Matplotlib 是一个用 Python 编程语言编写的、基于 NumPy 的开源数据可视化库。它提供了一套完整的兼容 MATLAB 的 API&#xff0c;支持各种常…

如何在华为OD机试中获得满分?Java实现【贪心的商人】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

Unity之2D碰撞器

1、什么是碰撞器 碰撞器是用于在物理系统中 表示物体体积的的&#xff08;形状或范围&#xff09; 刚体通过得到碰撞器的范围信息进行计算 判断两个物体的范围是否接触 如果接触 刚体就会模拟力的效果产生速度和旋转 2、参数 Edit Collider&#xff1a;编辑碰撞器 Material…

chatgpt赋能python:Python校验和的介绍

Python 校验和的介绍 在计算机科学中&#xff0c;校验和是一种用于检测数据传输中错误的简单方法。它可以用来确保数据在传输过程中没有发生丢失、损坏或篡改。Python语言中&#xff0c;我们可以通过各种方法来计算校验和。 常用的校验和算法 Python中常见的校验和算法包括&…