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

  实现同步的思想: 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. IT兄弟连 HTML5教程 HTML文档主体标记body

    在HTML的<body>和</body>标记中定义文档的主体,包含文档的所有内容(比如文本.超链接.图像.表格和列表等等).<body>标签有自己的属性,设置< ...

  2. 16-DRF工程搭建与序列化器

    1.DRF工程搭建 环境安装与配置 DRF是以Django扩展应用的方式提供的,所以我们可以直接利用Django环境,而无需创建(先创建Django环境). 1.安装DRF pip3 install ...

  3. My97Datepicker 日历控件的使用

    如果显示中乱码可以再改变lang  js包 中的  以防乱码 var $lang = {errAlertMsg: "\u4E0D\u5408\u6CD5\u7684\u65E5\u671F\ ...

  4. 前端之本地存储和jqueryUI

    本地存储 本地存储分为cookie,以及新增的localStorage和sessionStorage 1.cookie 存储在本地,容量最大4k,在同源的http请求时携带传递,损耗带宽,可设置访问路 ...

  5. java基础(19):List、Set

    1. List接口 我们掌握了Collection接口的使用后,再来看看Collection接口中的子类,他们都具备那些特性呢? 接下来,我们一起学习Collection中的常用几个子类(List集合 ...

  6. Python入门36道经典练习题

    [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? num_list=[] cou=0 for i in range(1,5): for j in rang ...

  7. 高强度学习训练第十二天总结:Java hashCode和equals的关系

    今天要收拾东西.草草的总结下.. 1.如果两个对象相等,则hashcode一定也是相同的 2.两个对象相等,对两个对象分别调用equals方法都返回true 3.两个对象有相同的hashcode值,它 ...

  8. Java基础--注解、反射

    一.注解(Annotation) 1.什么是注解? 从JDK5开始,Java增加了Annotation(注解),Annotation是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行 ...

  9. layui 学习笔记一:layui table 查询、新增、编辑、删除

    一.table数据的呈现(对应查询) 页面代码: @{ ViewBag.Title = "TableGrid"; } @section styles{ <link href= ...

  10. Java的包

    Java 包 Java面向对象的核心的概念:类.接口.抽象类.对象:[主体] 包的定义: 指的是一个程序的目录,在最早的时候,如果要开发一个程序,只需要定义一个Java文件,而后在这个文件中编写所需要 ...