C++ TCP客户端网络消息发送接收同步实现
废话不多说, 直入主题, 我们在写客户单的时候希望在哪里发消息出去,然后在哪里返回消息(同步), 然后继续往下运行-, 而不是在这里发送了一个消息给服务端, 在另一个地方接受消息(异步) , 也不知道等多久, 才收到消息, 等收到消息在通知发送消息的地方, 让程序继续往下运行, 这样想想异步实在太麻烦了,
实现同步的思想: 1 将socket设置成阻塞的, 2: 设置接受超时, 3: 消息类型区分
直接上代码
封装socket 头文件
#pragma once
#include <string>
#include <Winsock2.h> using namespace std;
class TcpSocket
{
public:
TcpSocket();
~TcpSocket(); bool SocketInit();
bool CreatSocket(string strIp, int nPort);
bool SendMsg(int msgType, string strSendBuf, string& strRecvMsg, int iTimeOut); private:
SOCKET m_Scoket;
DWORD m_dwVserion;
WSADATA m_WsData;
int m_iError;
bool m_isSocketFlag;
};
socket封装实现
#include "TcpSocket.h"
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996) TcpSocket::TcpSocket()
{
m_dwVserion = ;
m_isSocketFlag = true;
memset(&m_WsData, , sizeof(WSADATA));
} TcpSocket::~TcpSocket()
{
closesocket(m_Scoket);
WSACleanup();
} bool TcpSocket::SocketInit()
{
m_dwVserion = MAKEWORD(, );
m_iError = WSAStartup(m_dwVserion, &m_WsData);
if (m_iError != )
{
printf("socket 初始化操作失败");
m_isSocketFlag = false;
}
if (LOBYTE(m_WsData.wVersion) != && HIBYTE(m_WsData.wVersion) != )
{
WSACleanup();
m_isSocketFlag = false;
}
return m_isSocketFlag;
} bool TcpSocket::CreatSocket(string strIp, int nPort)
{
if (!m_isSocketFlag)
return false;
m_Scoket = socket(AF_INET, SOCK_STREAM, );
SOCKADDR_IN addr;
addr.sin_addr.S_un.S_addr = inet_addr(strIp.c_str());
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort); m_iError = connect(m_Scoket, (SOCKADDR*)&addr, sizeof(SOCKADDR));
if(m_iError != )
m_isSocketFlag = false;
return m_isSocketFlag;
} bool TcpSocket::SendMsg(int MsgType, string strSendBuf, string& strRecvMsg, int iTimeOut)
{
if (!m_isSocketFlag)
return false;
int timeOut = iTimeOut * ; //秒
setsockopt(m_Scoket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeOut, sizeof(timeOut));
setsockopt(m_Scoket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeOut, sizeof(timeOut));
printf("开始发送消息\n");
int iRet = send(m_Scoket, strSendBuf.c_str(), strSendBuf.length(), );
if (iRet == )
{
printf("发送消息超时\n");
return false;
}
printf("发送消息: %s\n", strSendBuf.c_str());
char recvBuf[] = { };
iRet = recv(m_Scoket, recvBuf, sizeof(recvBuf), );
if (iRet == -)
{
printf("接受消息超时\n");
return false;
}
string recvMsg = string(recvBuf);
if (recvMsg.find(to_string(MsgType)) == string::npos)
return false;
strRecvMsg = string(recvBuf);
return true;
}
测试程序:
#include <stdio.h>
#include "TcpSocket.h" int main()
{
TcpSocket client;
bool isRet = client.SocketInit();
if (!isRet)
return ;
isRet = client.CreatSocket("10.1.1.66", ); if (isRet)
{
while()
{
string strRecv = string();
client.SendMsg(, string("Hello"), strRecv, );
printf("接受消息: %s\n", strRecv.c_str());
Sleep();
}
}
getchar();
return ;
}
以上是个人拙见, 若有更好的方法请指教小弟, 谢谢! 谢谢! 谢谢!
C++ TCP客户端网络消息发送接收同步实现的更多相关文章
- activemq安装与简单消息发送接收实例
安装环境:Activemq5.11.1, jdk1.7(activemq5.11.1版本需要jdk升级到1.7),虚拟机: 192.168.147.131 [root@localhost softwa ...
- 在使用TCP协议进行消息发送时,对消息分帧
成帧与解析 阅读 <java TCP/IP Socket 编程>第三章笔记 成帧技术(frame)是解决如何在接收端定位消息的首尾位置的问题.在进行数据收发时,必须指定消息接收者如何确定何 ...
- XMPP客户端开发(2)--发送接收消息
客户端连接上服务器并登录以后,可以发送.接收消息. 首先需要定义Chat,MessageListener和ChatMessageListener几个变量: private static Chat ch ...
- 使用tcpdump监控网络消息发送
tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. tcpd ...
- TCP/IP网络
1. 简述osi七层模型和TCP/IP五层模型 一.OSI参考模型 今天我们先学习一下以太网最基本也是重要的知识——OSI参考模型. 1.OSI的来源 OSI(Op ...
- 一张图进阶 RocketMQ - 消息发送
前 言 三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!觉得不错的话,记得点赞关注哦. [重要]视频在 B 站同步更新,欢 ...
- ActiveMQ JMS实现消息发送
一.创建配置消息发送接收目的地. ActiveMQ中间件地址 JMS_BROKER_URL=failover://(tcp://192.168.1.231:61616) QUEUE_BUSP_TP_S ...
- [NIO]用dawn发送接收HTTP请求
HTTP协议的下层使用的是tcp.所以我们建立一个tcp连接就能发送接收http请求.dawn底层使用了nio.可是经过dawn的封装之后,我们在编写代码的时候,就和使用普通的堵塞式socket一样 ...
- Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)
一.实现功能 1.服务器端选择待发送的文件,可以是多个 2.开启服务器,支持多客户端接入,能够实时显示每个客户端接入状态 3.等待所有客户端都处于已连接状态时,依次发送文件集给每个客户端,显示每个客户 ...
随机推荐
- MacOS命令行打包+签名+公证+生成dmg文件
关于dmg文件是什么,和为什么要进行公证? 简单说下,dmg文件就是一个可直接在mac上安装的安装包,我自己的理解是就像windows上的exe安装包一样: 公证是将app传到苹果商店去做认证,如果不 ...
- Net中的并发锁
object _lock 锁的概念,这里不做详细阐述.先从最经典的应用场景来说,单例模式在不考虑静态构造函数实现的方式下,用锁实现是必须的.比如: public class Singleton { p ...
- swoole的process模块创建和使用子进程
swoole中为我们提供了一个进程管理模块 Process,替换PHP的 pcntl 扩展,方便我们创建进程,管理进程,和进程间的通信. swoole提供了2种进程间的通信: 1.基于 unix so ...
- Newtonsoft.Json 序列化踩坑之 IEnumerable
Newtonsoft.Json 序列化踩坑之 IEnumerable Intro Newtonsoft.Json 是 .NET 下最受欢迎 JSON 操作库,使用起来也是非常方便,有时候也可能会不小心 ...
- 死磕 java同步系列之AQS终篇(面试)
问题 (1)AQS的定位? (2)AQS的重要组成部分? (3)AQS运用的设计模式? (4)AQS的总体流程? 简介 AQS的全称是AbstractQueuedSynchronizer,它的定位是为 ...
- C# 简单的进程间通信方式
只想实现一个简单的进程建通信,有什么快速实现方式? 1 进程单例需求 / Windows 消息与 IMessageFilter 如果需求是实现一个进程单例,在启动第二个进程时,期望能自动唤起第一个进程 ...
- MySQL基础(MySQL5.7安装、配置)
写在前面: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQ ...
- Vuex基本使用的总结--转载
在 Vue 的单页面应用中使用,需要使用Vue.use(Vuex)调用插件.使用非常简单,只需要将其注入到Vue根实例中. import Vuex from 'vuex' Vue.use(Vuex) ...
- centos7 apache后台转nginx后台
背景 一开始买完服务器装的是用apache搭的后台, 现在想使用nginx, 希望对你有参考作用 查看系统版本信息 lsb_release -a 我的版本信息是 首先关闭apache-tomcat服务 ...
- Javascript中的几种函数
(1)普通函数:这种函数是我们日常使用中用的最多的,用function关键字定义的函数.这也是符合多种语言定义的. function foo(){ // code } (2)箭头函数:用=>运算 ...