当前位置: 首页 > news >正文

越秀网站建设优化坚持

越秀网站建设优化,坚持,城建网官网,网站该怎么找到c Socket实现客户端与服务器数据传输 这是自己第二次写博客,希望在博客记录自己的学习过程,欢迎大家评论! 实现: 客户端往服务器端发送一条数据,服务器端接收数据并输出; 服务器端再发送出接收到的数据给客户端! 根据自己的脑洞,想一下是否可以通过的改进实现简单的QQ聊天室…

c++ Socket实现客户端与服务器数据传输

这是自己第二次写博客,希望在博客记录自己的学习过程,欢迎大家评论!

实现: 客户端往服务器端发送一条数据,服务器端接收数据并输出;
服务器端再发送出接收到的数据给客户端!

根据自己的脑洞,想一下是否可以通过的改进实现简单的QQ聊天室!

少说废话,上代码

[文字描述都写在注释啦,也就那么点,]

服务器实现

一般情况下,先实现服务端的代码,这样逻辑可能会更清晰点,主要还是看个人的吧!
希望不要直接copy哦,至少自己动手敲一敲.

#define _WINSOCK_DEPRECATED_NO_WARNINGS 	//比较新版的vs,会警告我们不要使用一//下旧的函数,因为提供更新更安全的函数供我们使用,在这呢我们//还是用旧的吧,这个宏定义就是起屏蔽警告作用,VS下面也有提示的
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string>
#include<cstring>
#include<WS2tcpip.h>
#include <WinSock2.h>						//一般情况下,这个头文件位于windows.h之前,避免发生某些错误
#include<Windows.h>
#pragma comment(lib, "ws2_32.lib") 			//显示加载 ws2_32.dll	ws2_32.dll就是最新socket版本啦
using namespace std;int main()
{cout << "-----------服务器-----------" << endl;//	1	初始化WSADATA wsadata;WSAStartup(MAKEWORD(2, 2), &wsadata);	//make word,你把鼠标移到WSAStartup看看参数列表,是不是就是一个word啊//	2	创建服务器的套接字SOCKET serviceSocket;serviceSocket = socket(AF_INET, SOCK_STREAM, 0);	//socket(协议族,socket数据传输方式,某个协议)	我们默认为0,其实就是一个宏if (SOCKET_ERROR == serviceSocket) {	cout << "套接字闯创建失败!" << endl;}else {cout << "套接字创建成功!" << endl;}//	3	绑定套接字	指定绑定的IP地址和端口号sockaddr_in socketAddr;								//一个绑定地址:有IP地址,有端口号,有协议族socketAddr.sin_family = AF_INET;socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");		//代码开头第一行我们定义的宏在这就其作用啦socketAddr.sin_port = htons(1234);int bRes = bind(serviceSocket, (SOCKADDR*)&socketAddr, sizeof(SOCKADDR));	//绑定注意的一点就是记得强制类型转换if (SOCKET_ERROR == bRes) {cout << "绑定失败!" << endl;}else {cout << "绑定成功!" << endl;}//	4	服务器监听	int lLen = listen(serviceSocket, 5);	//监听的第二个参数就是:能存放多少个客户端请求,到并发编程的时候很有用哦if (SOCKET_ERROR == lLen) {cout << "监听失败!" << endl;}else {cout << "监听成功!" << endl;}//	5	接受请求sockaddr_in revClientAddr;SOCKET recvClientSocket = INVALID_SOCKET;	//初始化一个接受的客户端socketint _revSize = sizeof(sockaddr_in);recvClientSocket = accept(serviceSocket, (SOCKADDR*)&revClientAddr, &_revSize);if (INVALID_SOCKET == recvClientSocket) {cout << "服务端接受请求失败!" << endl;}else {cout << "服务端接受请求成功!" << endl;}//	6	发送/接受 数据char recvBuf[1024] = {};int reLen = recv(recvClientSocket, recvBuf, 1024, 0);int sLen = send(recvClientSocket, recvBuf, reLen, 0);if (SOCKET_ERROR == reLen) {cout << "服务端发送数据失败" << endl;}else {cout << "服务器接受到数据:    " << recvBuf << endl << endl;}//	7	关闭socketclosesocket(recvClientSocket);closesocket(serviceSocket);//	8	终止WSACleanup();cout << "服务器停止" << endl;cin.get();return 0;
}

客户端代码实现

在这里再提醒一点,运行程序的时候,我们是先运行服务端程序,再运行客户端程序.
所以有些同学可能会说"我们的代码都一样啊!怎么到我这就不成功了呢?",这是一个
低级的错误,我们要避免.

还有就是我还要强调,敲代码,像我一样的初学者,咋不能直接copy,慢慢敲,不急!
像我写博客也一样,慢慢写,不慌.

乍一看,客户端跟服务器端代码差不多啊!

也确实是,而且比服务器端还简单,在这里我就不再一个个写注释啦,其实跟上面的差不多,
少废话,开始吧!

#define _WINSOCK_DEPRECATED_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string>
#include<cstring>
#include<WS2tcpip.h>
#include <WinSock2.h>
#include<Windows.h>
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll
using namespace std;int main()
{cout << "-----------客户端-----------" << endl;//	1	初始化WSADATA wsadata;WSAStartup(MAKEWORD(2, 2), &wsadata);//	2	创建套接字SOCKET clientSocket = {};clientSocket = socket(PF_INET, SOCK_STREAM, 0);if (SOCKET_ERROR == clientSocket) {cout << "套接字闯创建失败!" << endl;}else {cout << "套接字创建成功!" << endl;}//	3	绑定套接字	指定绑定的IP地址和端口号sockaddr_in socketAddr;socketAddr.sin_family = PF_INET;socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");socketAddr.sin_port = htons(1234);int cRes = connect(clientSocket, (SOCKADDR*)&socketAddr, sizeof(SOCKADDR));if (SOCKET_ERROR == cRes) {cout << "客户端:\t\t与服务器连接失败....." << endl;	}else {cout << "客户端:\t\t与服务器连接成功....." << endl;		}//	4	发送请求char sendBuf[1024] = "from Client:   hello service.";send(clientSocket, sendBuf, strlen(sendBuf), 0);//	5	发送/接受 数据char recvBuf[1024] = {};recv(clientSocket, recvBuf, 1024, 0);cout << "客户端接收数据	:	" << recvBuf << endl << endl;//	6	关闭socketclosesocket(clientSocket);//	7	终止WSACleanup();cout << "客户端退出" << endl;cin.get();return 0;
}
这个就是运行效果啦

在这里插入图片描述

根据简单实现数据的发送和接受,我们一步一步改善代码

1. 首先使得客户端不断向服务器发送数据

发送数据: (也可以叫做请求,一般嘛,客户端都是向服务器端请求获得某资源).

更改代码,与上面一样,其余部分代码不做改变

服务器:
// 循环接收数据while (true){//	6	发送/接受 数据char recvBuf[4024] = {};int reLen = recv(recvClientSocket, recvBuf, 4024, 0);int sLen = send(recvClientSocket, recvBuf, reLen, 0);if (SOCKET_ERROR != reLen) {cout << "服务器接受到数据:    " << recvBuf << endl << endl;reLen = SOCKET_ERROR;}}
客户端:
while (true){//	4	发送请求string s;cout << "输入发送数据:   " << endl;getline(cin, s);					//可输入空格,默认以换行符结束输入,send(clientSocket, (char*)s.c_str(), s.length(), 0);//	5	发送/接受 数据char recvBuf[4024] = {};recv(clientSocket, recvBuf, 4024, 0);cout << "客户端接收数据	:	" << recvBuf << endl << endl;}

提示:代码更改仅仅是增加一个while循环,思路很清晰. 客户端我们从控制台输入发送数据,变得更主动

2.进一步改善,再服务器端处理简单的业务逻辑

作为学习,简单来说呢,就是获得客户端发送来的数据做一些处理(判断).

下面我们提供一个简单的例子(在服务器上做修改):

服务器:

相对于上一阶段,就是在while循环里面添加条件判断语句.
简单吧!

while (true){//	6	发送/接受 数据char recvBuf[1024] = {};int reLen = recv(recvClientSocket, recvBuf, 1024, 0);//阻塞函数,等待接受数据if (SOCKET_ERROR == reLen) {cout << "服务端发送数据失败" << endl;}else {cout << "请求命令:    " << recvBuf;if (0 == strcmp("cls", recvBuf)) {//服务端执行命令	system(recvBuf);		}// 中文请求仅仅是为了测试可行性,一般都是用英文else if(0 == strcmp("获取版本信息",recvBuf)) {//返回数据string verData = "Version: 1.0.1\nAuthor: Primer\nReleaseData: 2019-04-21";int sLen = send(recvClientSocket, (char*)verData.c_str(), verData.length(), 0);}else if(0 == strcmp("exit", recvBuf)){cout << endl << "退出服务器" << endl;break;}else {cout << "\t不正确..." << endl;}cout << endl;}}

客户端:

类似的修改,仅仅加了一个判断语句,不做过多的解释!

while (true){//	4	发送请求string s;cout << "输入发送数据:\t";getline(cin, s);									//可输入空格,默认以换行符结束输入,send(clientSocket, (char*)s.c_str(), (int)s.length(), 0);//因为recv接受函数是阻塞函数,所以我们加以判断//请求正确我才接收数据,否则不影响我继续请求if(0 == strcmp("获取版本信息", s.c_str())) {char recvBuf[4024] = {};int reLen = recv(clientSocket, recvBuf, 4024, 0);//阻塞函数,等待接受数据cout << endl << recvBuf << endl << endl;}}
效果图:

在这里插入图片描述

若要实现更多的逻辑处理,自己大开脑洞.

3.传输结构体到服务器

数据有着各种各样的类型,文字,图片,音频,视频等都是数据,有些数据复杂有些简单,
刚开始部分我们传输的是一个字符型或者整型的数据到服务器上,那么这此我们传输
稍微复杂一些的数据—结构体.

编不下去了.

上代码!

第一:

在客户端和服务器端定义一个结构一致的结构体.

什么叫结构一致?
你在结构体里面定义的基本类型顺序一定要相同,不然在读取数据的时候,
由于字节对齐不正确,可能读取出来的就是乱码
. 自己体会.

我的结构体是真这样子的.


//
// 定义一个学生结构体信息
typedef struct node {int		id;					//学号char	name[50];			//姓名char	sex[10];			//性别int		age;				//年龄char	className[100];		//班级}STUDENT;

服务器端:

一样的,仅仅改动while循环部分

	STUDENT student = {};//服务器接受数据,数据格式需要和客户端数据格式一致while (true){//	6	发送/接受 数据int reLen = recv(recvClientSocket, (char*)&student, 4024, 0);if (SOCKET_ERROR != reLen){cout << "服务端输出接受数据:  " << endl << endl;cout <<"学号:\t"<< student.id << endl;cout <<"姓名:\t"<< student.name << endl;cout <<"性别:\t"<< student.sex << endl;cout <<"年龄:\t"<< student.age << endl;cout <<"班级:\t"<< student.className << endl;memset(&student, 0, sizeof(student));}}

客户端:

更简单

	while (true){//	4	发送数据STUDENT student;cout << "输入学生信息:[学号+姓名+性别+年龄+专业班级]\t";cin >> student.id >> student.name >> student.sex >> student.age >> student.className;//在发送结构体的受强制转换 提供地址形式发送即可	send(clientSocket, (char*)&student, sizeof(student), 0);}

效果图:

在这里插入图片描述

http://www.lbrq.cn/news/2785267.html

相关文章:

  • 格尔木市公司网站建设比较成功的网络营销案例
  • 博罗网站建设哪家好军事新闻
  • 通辽企业网站建设b站推广网站2023
  • 校园二手网站设计论文一句话让客户主动找你
  • 网站制作素材网站泉州百度网站推广
  • 济南做网站价格陕西seo优化
  • 常州网站制作费用郑州网站优化哪家好
  • 网站设计 开发人员手机网站智能建站
  • 花卉网站建设的总结与市场调研报告
  • 茶企业网站建设模板网络公司取什么名字好
  • 石狮住房和城乡建设局网站苏州网站建设书生
  • 手机网站图片做多大百度浏览器下载
  • 模板性公司网站图片中国足彩网竞彩推荐
  • wap自助建站排板合肥头条今日头条新闻最新消息
  • 做网站app的工资高吗个人购买链接
  • 聊城网站建设品牌促销方法100种
  • 湖南企业做网站广州今日头条新闻最新
  • 建个简单的网站广州seo网站服务公司
  • 做字幕的网站外贸公司一般怎么找客户
  • 网红网站建设官网seo简介
  • wordpress科技网站模板今日新闻大事
  • 兰州网站建设最新招聘信息谷歌sem推广
  • 做网站什么分类流量多河南靠谱seo地址
  • 建网站那家好太原做网站的
  • 定制网站大概多少钱百度搜索广告价格
  • 广州微网站建设市场seo优化服务商
  • 金华企业制作网站推广seo优化公司
  • 网站建设答辩东莞seo建站公司哪家好
  • 网站流量报告seo基础入门教程
  • 邯郸制作网站的公司seo文章排名优化
  • Lecture 6 Kernels, Triton 课程笔记
  • JavaScript 性能优化:new Map vs Array.find() 查找速度深度对比
  • OpenTelemetry、Jaeger 与 Zipkin:分布式链路追踪方案对比与实践
  • 数字时代著作权侵权:一场资本与法律的博弈
  • 开放最短路径优先协议
  • 实践笔记-VSCode与IDE同步问题解决指南;程序总是进入中断服务程序。