废话不多说, 直入主题, 我们在写客户单的时候希望在哪里发消息出去,然后在哪里返回消息(同步), 然后继续往下运行-, 而不是在这里发送了一个消息给服务端, 在另一个地方接受消息(异步) , 也不知道等多久, 才收到消息, 等收到消息在通知发送消息的地方, 让程序继续往下运行, 这样想想异步实在太麻烦了,

  实现同步的思想: 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客户端网络消息发送接收同步实现的更多相关文章

  1. activemq安装与简单消息发送接收实例

    安装环境:Activemq5.11.1, jdk1.7(activemq5.11.1版本需要jdk升级到1.7),虚拟机: 192.168.147.131 [root@localhost softwa ...

  2. 在使用TCP协议进行消息发送时,对消息分帧

    成帧与解析 阅读 <java TCP/IP Socket 编程>第三章笔记 成帧技术(frame)是解决如何在接收端定位消息的首尾位置的问题.在进行数据收发时,必须指定消息接收者如何确定何 ...

  3. XMPP客户端开发(2)--发送接收消息

    客户端连接上服务器并登录以后,可以发送.接收消息. 首先需要定义Chat,MessageListener和ChatMessageListener几个变量: private static Chat ch ...

  4. 使用tcpdump监控网络消息发送

    tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. tcpd ...

  5. TCP/IP网络

    1.  简述osi七层模型和TCP/IP五层模型 一.OSI参考模型         今天我们先学习一下以太网最基本也是重要的知识——OSI参考模型.  1.OSI的来源         OSI(Op ...

  6. 一张图进阶 RocketMQ - 消息发送

    前 言 三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!觉得不错的话,记得点赞关注哦. [重要]视频在 B 站同步更新,欢 ...

  7. ActiveMQ JMS实现消息发送

    一.创建配置消息发送接收目的地. ActiveMQ中间件地址 JMS_BROKER_URL=failover://(tcp://192.168.1.231:61616) QUEUE_BUSP_TP_S ...

  8. [NIO]用dawn发送接收HTTP请求

    HTTP协议的下层使用的是tcp.所以我们建立一个tcp连接就能发送接收http请求.dawn底层使用了nio.可是经过dawn的封装之后,我们在编写代码的时候,就和使用普通的堵塞式socket一样 ...

  9. Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)

    一.实现功能 1.服务器端选择待发送的文件,可以是多个 2.开启服务器,支持多客户端接入,能够实时显示每个客户端接入状态 3.等待所有客户端都处于已连接状态时,依次发送文件集给每个客户端,显示每个客户 ...

随机推荐

  1. JavaScript:ES6的新特性

    1.关键字 const:修饰常量.ES6之前只有变量的声明字段var,ES6开始引入常量关键字,被修饰的变量无法被修改. <script type="text/javascript&q ...

  2. python做中学(六)os.getcwd() 的用法

    概述 os.getcwd() 方法用于返回当前工作目录. 语法 getcwd()方法语法格式如下: os.getcwd() 参数 无 返回值 返回当前进程的工作目录. 实例 以下实例演示了 getcw ...

  3. Find 查找命令时过滤掉某些文件或目录 以及 -maxdepth、-mindepth的用法

    1)find过滤目录使用find命令在linux系统中查找文件时,有时需要忽略某些目录,可以使用"-path 过滤的目录路径 -prune -o"参数来进行过滤.不过必须注意:要忽 ...

  4. JXL工具包对Excle文件操作

    1.简介: XL - JXL(Java Excel API)是一个用来动态读写 Excel 文件的开源框架,利用它可以 在任何支持 Java 的操作系统上动态读写 Excel 文件. 2.开发步骤 1 ...

  5. java.lang.ClassNotFoundException: XXX (no security manager: RMI class loader disabled)

    在搞RMI远程发布,consumer去获取rmi远程服务的代理对象的时候出现了如下的错误 问题发现: 由于我发布的对象的包路径和获取的对象的包路径不一致,导致了这样的问题 解决方案: 包路径改为一致就 ...

  6. Gallery -- 横向不断滚动 demo

    <%@ Page Language="C#" AutoEventWireup="true" %> <!DOCTYPE html> < ...

  7. 初识Lock与AbstractQueuedSynchronizer(AQS)

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  8. selenium设置user-agent以及对于是否是浏览器内核进行反爬

    (Session info: chrome=75.0.3770.90),不同版本方法可能会有些不同 推荐查资料网站必应可以避开一堆广告 一.user-agent设置 from selenium imp ...

  9. 高强度学习训练第十一天总结:Class文件结构(二)

    常量池 可以理解为Class文件之中的资源仓库,他是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一 访问标志 在常量池结束后,紧接着的俩个字节代表访问标 ...

  10. [转]The Regular Expression Object Model

    本文转自:https://docs.microsoft.com/en-us/dotnet/standard/base-types/the-regular-expression-object-model ...