网络编程学习记录

news2025/1/15 23:37:59

 服务端首先是确定协议版本。首先定义一个结构体

WSADATA wsadata;

这个结构体是啥呢?

是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。大家晓得了吧。

让我们看看这个结构体。

typedef struct WSAData {
  WORD           wVersion;            //低位字节指定主版本号。
  WORD           wHighVersion;        //高阶字节指定次要版本号;
  char           szDescription[WSADESCRIPTION_LEN+1];//
  char           szSystemStatus[WSASYS_STATUS_LEN+1];//
  unsigned short iMaxSockets;//
  unsigned short iMaxUdpDg;//
  char FAR       *lpVendorInfo;//
} WSADATA, *LPWSADATA;

然后调用下面这个函数启动对winsock dll的使用,那么就要判断这个函数是否要成功 

if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
{
    cout <<"启动失败!"<<endl;
    return;
}

启动以后就要判断高低字节位有没有问题。

	//判断高低版本对不对
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
	{
		cout << "版本不对" << endl;
		return;
	}
	//1.确定协议版本
	//定义一个结构体
	WSADATA wsadata;
	//启动winsock dll,返回值不为零即为启动失败
	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		cout << "调用winscok.dll 失败" << endl;
		return -1;
	}
	cout << "调用winscok.dll 失败\n" << endl;
	//判断高低版本对不对
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
	{
		cout << "版本不对,%d" << GetLastError() << endl;
		return -1;
	}
	cout << "版本正确"<< endl;

第二步,创建socket,分配套接字句柄

 第一个SOCK_STREAM(缺省函数):

 这里采用INET,tcp协议。

	//2.创建socket
	SOCKET servicesocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (servicesocket == SOCKET_ERROR)
	{
		cout << "创建socket失败!" << endl;
		//因为创建失败,使用要清理协议版本信息
		WSACleanup();
		return -1;
	}
	cout << "创建socket成功!" << endl;

第三步,确定协议地址簇

typedef struct sockaddr_in {
  ADDRESS_FAMILY sin_family;
  USHORT         sin_port;
  IN_ADDR        sin_addr;
  CHAR           sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

SOCKADDR_IN结构为AF_INET地址系列指定传输地址和端口。


	//3.确定协议地址簇, SOCKADDR_IN结构为AF_INET地址系列指定传输地址和端口
	SOCKADDR_IN addr = { 0 };
	addr.sin_family = AF_INET;	//与socket保持一致
	addr.sin_addr.S_un.S_addr = inet_addr("192.168.31.167");//输入服务端的ip地址,要注意转换
	addr.sin_port = htonl(11223);//注意大小端,还有尽量不占用其他应用端口号,要吧端口号设置大一点

 第四步 绑定

	//4.绑定 把socket和协议地址簇绑定
	if (-1 == bind(servicesocket, (sockaddr*)&addr, sizeof addr))
	{
		cout << "绑定失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "绑定成功" << endl;

第五步 监听

	//5.监听
	//监听的数量
	if (listen(servicesocket, 10) == -1)
	{
		cout << "监听失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "监听成功" << endl;

第六步 连接

调用此成员函数以接受套接字上的连接。

virtual BOOL Accept( 
   CAsyncSocket& rConnectedSocket, 
   SOCKADDR* lpSockAddr = NULL, 
   int* lpSockAddrLen = NULL  
);
	//6.接受客户端连接
	SOCKET clientsocket = accept(servicesocket,(sockaddr*)NULL,(int*)NULL);
	if (clientsocket == SOCKET_ERROR)
	{
		cout << "客户端连接失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "连接成功" << endl;

第七步 通信

recv函数从连接的套接字或绑定的无连接套接字接收数据

int recv(
  _In_   SOCKET s,
  _Out_  char *buf,
  _In_   int len,
  _In_   int flags
);
	//7.通信
	char buffer[256];
	while (1)
	{
		int num = recv(servicesocket,buffer,255,NULL);
		buffer[num] = 0;
		cout << buffer << endl;
	}

第八步 关闭

		closesocket(servicesocket);

第九步 清理


WSACleanup();

总的服务端代码:

#include <iostream>
#include <Winsock2.h>
#pragma comment (lib,"ws2_32.lib")
using namespace std;

int main(void)
{
	//1.确定协议版本
	//定义一个结构体
	WSADATA wsadata;
	//启动winsock dll,返回值不为零即为启动失败
	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		cout << "调用winscok.dll 失败" << endl;
		return -1;
	}
	cout << "调用winscok.dll 成功\n" << endl;
	//判断高低版本对不对
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
	{
		cout << "版本不对,%d" << GetLastError() << endl;
		return -1;
	}
	cout << "版本正确"<< endl;

	//2.创建socket
	SOCKET servicesocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (servicesocket == SOCKET_ERROR)
	{
		cout << "创建socket失败!" << endl;
		//因为创建失败,使用要清理协议版本信息
		WSACleanup();
		return -1;
	}
	cout << "创建socket成功!" << endl;
	
	//3.确定协议地址簇, SOCKADDR_IN结构为AF_INET地址系列指定传输地址和端口
	SOCKADDR_IN addr = { 0 };
	addr.sin_family = AF_INET;	//与socket保持一致
	addr.sin_addr.S_un.S_addr = inet_addr("192.168.31.167");//输入服务端的ip地址,要注意转换
	addr.sin_port = htons(11223);//注意大小端,还有尽量不占用其他应用端口号,要吧端口号设置大一点
	
	//4.绑定 把socket和协议地址簇绑定
	if (-1 == bind(servicesocket, (sockaddr*)&addr, sizeof addr))
	{
		cout << "绑定失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "绑定成功" << endl;
	//5.监听
	//监听的数量
	if (listen(servicesocket, 10) == -1)
	{
		cout << "监听失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "监听成功" << endl;
	//6.接受客户端连接
	SOCKET clientsocket = accept(servicesocket,(sockaddr*)NULL,(int*)NULL);
	if (clientsocket == SOCKET_ERROR)
	{
		cout << "客户端连接失败!" << endl;
		//那就要关闭socket,然后清理协议
		closesocket(servicesocket);
		WSACleanup();
		return -1;
	}
	cout << "连接成功" << endl;
	//7.通信
	char buffer[256];
	while (1)
	{
		cout << "开始通信" << endl;
		int num = recv(servicesocket,buffer,255,NULL);
		buffer[num] = 0;
		cout << buffer << endl;
	}

	//8.断开连接
	closesocket(servicesocket);

	//9.清理版本协议信息
	WSACleanup();



	return 0;
}

接下来是客户端

客户端同理啦

只要一个连接服务端和通信有点区别

#include <iostream>

//添加头文件
#include <winsock2.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")

using namespace std;

int main(void)
{
	//1.确定协议版本
	WSADATA cwsadata;
	if (WSAStartup(MAKEWORD(2, 2), &cwsadata) != 0)
	{
		cout << "确定协议版本失败" << endl;
		return -1;
	}
	cout << "确定协议版本成功" << endl;
	//判断高低版本
	if (LOBYTE(cwsadata.wVersion) != 2 || HIBYTE(cwsadata.wHighVersion) != 2)
	{
		cout << "版本错误" << endl;
		return -1;
	}
	cout << "版本正确" << endl;


	//2.创建socket
	SOCKET clientsocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (clientsocket == SOCKET_ERROR)
	{
		cout << "创建socket失败" << endl;
		closesocket(clientsocket);
		WSACleanup();
		return -1;
	}

	//3获取服务器协议簇
	SOCKADDR_IN addr = { 0 };
	addr.sin_family = AF_INET;
	addr.sin_addr.S_un.S_addr = inet_addr("192.168.31.167");
	addr.sin_port = htons(11223);

	//4连接服务器
	if (connect(clientsocket, (sockaddr*)&addr, sizeof addr) == SOCKET_ERROR)
	{
		cout << "连接失败" << GetLastError() << endl;
		closesocket(clientsocket);
		WSACleanup();
		return -1;
	}
	cout << "连接成功" << endl;

	//5通信
	char buffer[256];
	while (1)
	{
        cout <<"开始通信:";
		cin >> buffer;
		send(clientsocket, buffer, strlen(buffer), NULL);
	}


	//6关闭
	closesocket(clientsocket);

	//7清理
	WSACleanup();
	return 0;
}

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

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

相关文章

c++ socket之io复用模型 epoll进阶

服务器开发系列 文章目录服务器开发系列前言一、socket epoll介绍二、代码实现1. epoll client实现2. epoll server实现3. epoll client server验证总结前言 I/O复用模型&#xff1a;主要是指&#xff0c;一个线程可以同时监控多个系统IO、并且能够操作多个系统IO的一种技术模…

西瓜书第一章课后题答案(一)

1.1 针对西瓜分类分题进行讲解属性&#xff1a; 3个属性色泽&#xff1a;&#xff08;青绿&#xff0c;乌黑&#xff0c;浅白&#xff09;根蒂&#xff1a;&#xff08;蜷缩&#xff0c;硬挺&#xff0c;稍蜷&#xff09;敲声&#xff1a;&#xff08;浊响&#xff0c;清脆&…

Docker网络network详解

一、概述 Docker容器每次重启后容器ip是会发生变化的。 这也意味着如果容器间使用ip地址来进行通信的话&#xff0c;一旦有容器重启&#xff0c;重启的容器将不再能被访问到。 而Docker 网络就能够解决这个问题。 Docker 网络主要有以下两个作用&#xff1a; 容器间的互联和…

【ROS2入门】理解 ROS 2 节点

大家好&#xff0c;我是虎哥&#xff0c;从今天开始&#xff0c;我将花一段时间&#xff0c;开始将自己从ROS1切换到ROS2&#xff0c;在上一篇中&#xff0c;我们依托Turtlesim演示节点来逐步展开&#xff0c;介绍了rqt工具&#xff0c;这一章&#xff0c;我们将围绕ROS2中主要…

jvm快速入门

1.JVM介绍 1.什么是jvm Java Virtual Machine&#xff08;java二进制字节码运行环境&#xff09; 好处&#xff1a; 一次编译&#xff0c;好处运行自动内存管理&#xff0c;垃圾回收机制数组下标越界检查多态 比较JVM\JRE\JDK jvm屏蔽java代码与底层操作系统的差异 JREJVM基…

基于 java springboot+layui仓库管理系统设计和实现

基于 java springbootlayui仓库管理系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码…

基于基于jsp+mysql+Spring+mybatis的SSM汽车保险理赔管理系统设计和实现

基于基于jspmysqlSpringmybatis的SSM汽车保险理赔管理系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐…

12图、网络、关联矩阵

第 12 讲 图、网络、关联矩阵 Graphs&#xff0c;networks&#xff0c;incidence matrices 本讲讨论线性代数在物理系统中的应用。 图和网络 Graphs & Networks “图”就是“结点”和“边”的一个集合。 边线上的箭头代表从结点流出的正方向。 关联矩阵&#xff08;I…

独立开发变现周刊(第87期):靠写简历如何每年赚24万美元?

分享独立开发、产品变现相关内容&#xff0c;每周五发布。目录1、mall4cloud: 开源的微服务B2B2C电商商城系统2、restorePhotos&#xff1a;开源的老照片修复系统3、JSON Crack——开源、免费的JSON可视化应用程序4、靠写简历如何每年赚24万美元&#xff1f;1、mall4cloud: 开源…

干货:用户分析的六大方法论(一)

​在日常的用户分析中&#xff0c;常用的有六大分析方法论&#xff1a; 1、行为事件分析2、点击分析模型3、用户行为路径分析4、用户健康度分析5、漏斗模型6、用户画像分析 1.行为事件分析 “行为事件分析”是用户分析的第一步&#xff0c;也是用户分析的核心和基础。一般来说…

代码随想录训练营第五十九天

1.下一个更大元素II 题503 循环数组有两种方法&#xff0c;一是用同一个数组拼接成两个数组&#xff0c;实现假循环&#xff1b;二是遍历两遍&#xff0c;用求余的方法。求余的方法更简便。 class Solution { public:vector<int> nextGreaterElements(vector<int>…

虚拟化技术学习笔记9

KVM存储虚拟化配置&#xff1a; 学习目标&#xff1a; 能够通过virt-manager添加硬盘&#xff1b;能够通过virsh添加硬盘&#xff1b;能够通过xml文件添加硬盘&#xff1b;能够了解本地存储的作用&#xff1b;能够设置本地存储&#xff1b;能够了解网络存储的作用&#xff1b…

黑马程序员SSM框架教程_Spring+SpringMVC+MyBatisPlus笔记(自学用,持续更新)

Spring的实现有两种方式&#xff0c;一是配置&#xff0c;二是注解 目录Spring_day01IOC、DIBean的基本配置、实例化、生命周期Bean的基本配置bean的实例化训练中的不足1&#xff1a;bean的生命周期DI相关内容setter注入构造器注入小结自动注入集合注入Spring_day02Spring_day0…

深入理解计算机系统_程序的加载过程和运行过程

这篇博客记录编译得到可执行目标文件后&#xff0c;加载和运行的过程。 编译得到可执行目标文件后&#xff0c;就可以将“可执行目标文件”加载“运行地址”所指的内存位置&#xff0c;然后运行了。下面记录Linux虚拟内存运行的运行过程。 2.1 程序的加载过程 当在windows下双…

【Java AWT 图形界面编程】LayoutManager 布局管理器 ③ ( BorderLayout 布局 )

文章目录一、BorderLayout 布局二、BorderLayout 构造函数 API三、BorderLayout 代码示例1、BorderLayout 基本用法代码示例2、BorderLayout 区域占用代码示例3、BorderLayout 同一区域显示多个组件代码示例一、BorderLayout 布局 BorderLayout 布局 将 Container 容器 分割成 …

深度学习PyTorch 之 DNN-二分类

本节开始说一下DNN分类的pytorch实现&#xff0c;先说一下二分类 流程还是跟前面一样 #mermaid-svg-7Bxg4CYlbKjYOMMf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-7Bxg4CYlbKjYOMMf .error-icon{fill:#552222;}…

从校园到职场,听听他们的成长之路

背景介绍 这次分享主题是「从校园到职场 -- 我的成长之路」&#xff0c;视频内容可以查看 B 站链接&#xff1a;从校园到实习再到秋招。 上次的面试分享之后&#xff0c;阿卡拉提到关于刚毕业的学生也会有很多找工作的困扰&#xff0c;而且这个阶段能获取到的信息相对比较有限&…

Java API文档的使用详解

文章目录1. 概念2. 使用Java编程基础教程系列学会使用 API 文档是一个开发者基本的素养&#xff0c;而许多初学者并不会在意 API 文档的使用&#xff0c;甚至从来没有接触过&#xff0c;所以写下这篇文章探讨 API 文档的使用&#xff0c;希望能够帮助到你&#xff0c;先赞后看&…

正点原子嵌入式linux第二期

目录 第5讲 IMX6U芯片介绍 第6讲 6.1汇编LED驱动实验-原理分析 6.2 汇编LED驱动实验-汇编基本语法 ​编辑6.3 驱动编写 6.4 编写驱动 6.5烧写bin文件到SD卡并运行 第七讲 IMX启动方式&#xff08;没怎么听懂&#xff09; 7.1启动设备的选择 7.2 IVT表和BootData详解 7.3D…

从面试官的角度带你从源码分析关于vue(v2.7.10)的面试题

我们在面试的时候经常会被问到vue框架的原理类问题&#xff0c;我今天整理了一些常见问题和答案&#xff0c;希望有不正确之处还请指正。 1.new Vue时发生了什么 首先实例化一个对象&#xff0c;该对象执行init方法初始化生命周期等等&#xff0c;随后执行$mount方法开始生成v…