首页 > 其他分享 >ARS展览项目(六)——Socket通信

ARS展览项目(六)——Socket通信

时间:2024-09-24 10:16:10浏览次数:1  
标签:ARS addr int send server len 展览 buf Socket

本篇前提说明

因为我这边做的是表情识别,另外一边做的是贪吃蛇的动作。贪吃蛇的食物就是我的表情,所以要把两者的数据连接起来。

贪吃蛇用JAVA来做,我用C++,然后两者可以用Socket来进行数据连接。设计时候是贪吃蛇用客户端,我这边是服务端

本项目在该文档的基础上修改,https://blog.csdn.net/qq_27923041/article/details/83857964,谢谢这位作者的帮助。

先放上代码

服务端的代码(Server端)

//#include "pch.h"
#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void initialization();
int main() {
	//定义长度变量
	int send_len = 0;
	int recv_len = 0;
	int len = 0;
	//定义发送缓冲区和接受缓冲区
	char send_buf[100];
	char recv_buf[100];
	//定义服务端套接字,接受请求套接字
	SOCKET s_server;
	SOCKET s_accept;
	//服务端地址客户端地址
	SOCKADDR_IN server_addr;
	SOCKADDR_IN accept_addr;
	initialization();
	//填充服务端信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(5010);
	//创建套接字
	s_server = socket(AF_INET, SOCK_STREAM, 0);
	if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "套接字绑定失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字绑定成功!" << endl;
	}
	//设置套接字为监听状态
	if (listen(s_server, SOMAXCONN) < 0) {
		cout << "设置监听状态失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "设置监听状态成功!" << endl;
	}
	cout << "服务端正在监听连接,请稍候...." << endl;
	//接受连接请求
	len = sizeof(SOCKADDR);
	s_accept = accept(s_server, (SOCKADDR *)&accept_addr, &len);
	if (s_accept == SOCKET_ERROR) {
		cout << "连接失败!" << endl;
		WSACleanup();
		return 0;
	}
	cout << "连接建立,准备接受数据" << endl;
	//接收数据
	while (1) {
		recv_len = recv(s_accept, recv_buf, 100, 0);
		if (recv_len < 0) {
			cout << "接受失败!" << endl;
			break;
		}
		else {
			cout << "客户端信息:" << recv_buf << endl;
		}
		cout << "请输入回复信息:";
		cin >> send_buf;
		send_len = send(s_accept, send_buf, 100, 0);
		if (send_len < 0) {
			cout << "发送失败!" << endl;
			break;
		}
	}
	//关闭套接字
	closesocket(s_server);
	closesocket(s_accept);
	//释放DLL资源
	WSACleanup();
	return 0;
}
void initialization() {
	//初始化套接字库
	WORD w_req = MAKEWORD(2, 2);//版本号
	WSADATA wsadata;
	int err;
	err = WSAStartup(w_req, &wsadata);
	if (err != 0) {
		cout << "初始化套接字库失败!" << endl;
	}
	else {
		cout << "初始化套接字库成功!" << endl;
	}
	//检测版本号
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
		cout << "套接字库版本号不符!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字库版本正确!" << endl;
	}
	//填充服务端地址信息
}

客户端代码(CLient端)

//#include "pch.h"
#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void initialization();
int main() {
	//定义长度变量
	int send_len = 0;
	int recv_len = 0;
	//定义发送缓冲区和接受缓冲区
	char send_buf[100];
	char recv_buf[100];
	//定义服务端套接字,接受请求套接字
	SOCKET s_server;
	//服务端地址客户端地址
	SOCKADDR_IN server_addr;
	initialization();
	//填充服务端信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	server_addr.sin_port = htons(5010);
	//创建套接字
	s_server = socket(AF_INET, SOCK_STREAM, 0);
	if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "服务器连接失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "服务器连接成功!" << endl;
	}
 
	//发送,接收数据
	while (1) {
		cout << "请输入发送信息:";
		cin >> send_buf;
		send_len = send(s_server, send_buf, 100, 0);
		if (send_len < 0) {
			cout << "发送失败!" << endl;
			break;
		}
		recv_len = recv(s_server, recv_buf, 100, 0);
		if (recv_len < 0) {
			cout << "接受失败!" << endl;
			break;
		}
		else {
			cout << "服务端信息:" << recv_buf << endl;
		} 
	}
	//关闭套接字
	closesocket(s_server);
	//释放DLL资源
	WSACleanup();
	return 0;
}
void initialization() {
	//初始化套接字库
	WORD w_req = MAKEWORD(2, 2);//版本号
	WSADATA wsadata;
	int err;
	err = WSAStartup(w_req, &wsadata);
	if (err != 0) {
		cout << "初始化套接字库失败!" << endl;
	}
	else {
		cout << "初始化套接字库成功!" << endl;
	}
	//检测版本号
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
		cout << "套接字库版本号不符!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字库版本正确!" << endl;
	}
	//填充服务端地址信息
}

说明

因为我这边做的是表情识别,另外一边做的是贪吃蛇的动作。贪吃蛇的食物就是我的表情,所以要把两者的数据连接起来。

贪吃蛇用JAVA来做,我用C++,然后两者可以用Socket来进行数据连接。设计时候是贪吃蛇用客户端,我这边是服务端

设计了:

发送数据 代表表情
1 开心(happy)
2 平常(common)
3 厌恶(disgust)
4 生气(angry)

这里之所以放客户端的代码,我是拿来测试服务端改得好不好的,所以整个项目过程中我都没有改过客户端的代码,生成一个exe就可以一直用。

程序直接新建一个C++空项目,导入opencv和dlib属性表,加入cpp源文件就可以用。建立两个项目,一个服务端,一个客户端。

解决的一个难点

Socket通信的问题容易解决,让它改成自动发送数据也好解决,但是整合的时候发现!!Socket加入opencv或dlib的库编译时,会无法建立监听。

后来一步步排除原因,有计算机的同学帮忙,发现是socket和opencv与dlib的命名空间发生了冲突,就是using namespace stu;不正常。

于是计算机的同学想到一个很好的方法,把Socket写在不同文件中,再写一个头文件来引用,那么两者的命名空间便不会冲突,因为是不同的cpp文件,如下:

新建一个头文件 1.h

#pragma once
#ifndef XXX_H
#define XXX_H

void aaa(int ax);

#endif

新建一个1.cpp 拿来放Socket的代码

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

void initialization();

extern int b_int;

void aaa(int a) 
{
	a = b_int;
	//定义长度变量
	int send_len = 0;
	int recv_len = 0;
	int len = 0;
	//定义发送缓冲区和接受缓冲区
	char send_buf[100];
	char recv_buf[100];
	//定义服务端套接字,接受请求套接字
	SOCKET s_server;
	SOCKET s_accept;
	//服务端地址客户端地址
	SOCKADDR_IN server_addr;
	SOCKADDR_IN accept_addr;
	initialization();
	//填充服务端信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(5010);

	//创建套接字
	s_server = socket(AF_INET, SOCK_STREAM, 0);
	bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));

	//设置套接字为监听状态
	listen(s_server, SOMAXCONN);

	//接受连接请求
	len = sizeof(SOCKADDR);
	s_accept = accept(s_server, (SOCKADDR *)&accept_addr, &len);

	//接收数据
	while (1)
	{
		if (a == 1) 
		{
			send_buf[0] = '1';
			send_buf[1] = '\0';
		}
		else if (a == 2)
		{
			send_buf[0] = '2';
			send_buf[1] = '\0';
		}
		else if (a == 3)
		{
			send_buf[0] = '3';
			send_buf[1] = '\0';
		}
		else if (a == 4)
		{
			send_buf[0] = '4';
			send_buf[1] = '\0';
		}

		send_len = send(s_accept, send_buf, 100, 0);
	}
}
void initialization() {
	//初始化套接字库
	WORD w_req = MAKEWORD(2, 2);//版本号
	WSADATA wsadata;
	int err;
	err = WSAStartup(w_req, &wsadata);
	if (err != 0) {
		cout << "初始化套接字库失败!" << endl;
	}
	else {
		cout << "初始化套接字库成功!" << endl;
	}
	//检测版本号
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
		cout << "套接字库版本号不符!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字库版本正确!" << endl;
	}
	//填充服务端地址信息
}

新建一个2.cpp 拿来放main()函数

#include"1.h"
#include <iostream>
#include <thread>
#include<math.h>
using namespace std;

int b_int = 1;
extern void aaa(int a);

int main()
{
	int ccc = 2 ;
	b_int = ccc;
	std::thread t(aaa, b_int);
	t.join();
	//aaa(b_int);
	//cout <<b_int <<endl ;
	return 0;
}

其中,std::thread t(aaa, b_int);t.join();是多线程的动作,会在下一篇文章解释。#include <thread>是多线程的头文件。

在这里,多文件和写库就可以了。

标签:ARS,addr,int,send,server,len,展览,buf,Socket
From: https://www.cnblogs.com/atanchen/p/18428489

相关文章

  • ARS展览项目(五)——表情识别测试
    这个表情识别项目的第三步下面是代码,作用是可以进行表情识别。本篇博客的实现方法参照了https://blog.csdn.net/zmdsjtu/article/details/53667929,这个很好用,感谢这位博主。#pragmacomment(linker,"/subsystem:windows/entry:mainCRTStartup")//去除CMD窗口#include<dlib/......
  • ARS展览项目(三)——识别面部得到特征点
    这个表情识别项目的第一步下面是代码,作用是识别出人脸,并且把人脸标记为68个特征点。然后把每次识别的一组(68个数据)保存在.txt文件里,一秒识别n次,那么一秒就生成n个txt本篇博客的实现方法参照了https://blog.csdn.net/zmdsjtu/article/details/53667929,这个很好用,感谢这位博主。......
  • ARS展览项目(二)——环境搭建:opencv、dlib、VS2017
    先说用到的软件和函数库VS2017——我用VS2017社区版来开发,原因是软件免费而且好用,本项目用C++来做opencv——OpenComputerVision是计算机视觉的库,有多种语言的接口,而且函数库也很丰富dlib——Dlib是一个包含机器学习算法的C++开源工具包,提供大量的机器学习/图像处理算法(网......
  • ARS展览项目(七)——C-多线程:Socket-表情识别整合
    说明一下我这边做表情识别和Socket,表情识别要实时,Socket要一直监听表情识别的结果,那么就只好用C++多线程来解决这个“两个功能一直并且同时运行”的问题。否则,如果是单线程的话,只能运行表情识别一段时间,切换发送一段时间,又切换回来,这样没有多线程好。还要说解决的难点写成多......
  • QCustomPlot QCPBars横向柱状图示例
    #include"qcustomplot.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);QCustomPlotcustomPlot;customPlot.resize(700,500);customPlot.show();QCPAxis*keyAxis=customPlot.yAxis;QCPAxis*valueAxis=......
  • QCustomPlot QCPBars纵向柱状图示例
    #include"qcustomplot.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);QCustomPlotcustomPlot;customPlot.resize(700,500);customPlot.show();QCPAxis*keyAxis=customPlot.xAxis;QCPAxis*valueAxis=......
  • socket通信中的大小端问题及解决措施
    本人一直有个疑惑,大小端通信怎么存储(以前一直知道这个概念,但怎么都跟实际匹配不上,网络上也并没有说怎么处理大小端通信问题)socket通信中addr需要转换成网络字节序,也就是大端助记:htonlh->host缩写n->net缩写l是类型缩写(l->long ll->longlongsshort都是无符......
  • qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed加
    qDebug()<<"QSslSocket="<<QSslSocket::sslLibraryBuildVersionString();qDebug()<<"OpenSSL支持情况:"<<QSslSocket::supportsSsl();打印需要的版本和当前openssl的支持情况如果显示false,不支持就是说明,不支持加密对应下载版本的openssl进行重新编译即可原因......
  • WebSocket相关知识点
    文章目录一、数据实时推送实现1.轮询(Polling)2.长连接(LongPolling)3.WebSocket二、代码实现后端实现1.引入依赖2.配置类3.WebSocket服务类4.定时任务前端实现测试工具推荐三、常见错误及解决方案错误1:参数缺失或注解错误错误2:遍历集合时修改集合导致的并......
  • Can't connect to local MySQL server through socket
    mysql-urootERROR2002(HY000):Can'tconnecttolocalMySQLserverthroughsocket'/tmp/mysql.sock'(2)这是mysql登录时找不到套接字的问题。首先需要明白的是,Linux端的mysqlserver启动时会开启一个socket,Linux上的MySQL的客户端在不使用IP连接时mysqlserver时,默认......