博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ TCP客户端网络消息发送接收同步实现
阅读量:4625 次
发布时间:2019-06-09

本文共 3138 字,大约阅读时间需要 10 分钟。

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

  实现同步的思想: 1 将socket设置成阻塞的, 2: 设置接受超时, 3: 消息类型区分

直接上代码

封装socket 头文件

#pragma once#include 
#include
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 = 0;    m_isSocketFlag = true;    memset(&m_WsData, 0, sizeof(WSADATA));}TcpSocket::~TcpSocket(){    closesocket(m_Scoket);    WSACleanup();}bool TcpSocket::SocketInit(){    m_dwVserion = MAKEWORD(1, 1);    m_iError = WSAStartup(m_dwVserion, &m_WsData);    if (m_iError != 0)    {        printf("socket 初始化操作失败");        m_isSocketFlag = false;    }    if (LOBYTE(m_WsData.wVersion) != 1 && HIBYTE(m_WsData.wVersion) != 1)    {        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, 0);    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 != 0)        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 * 1000 ;        //秒    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(), 0);    if (iRet == 0)    {        printf("发送消息超时\n");        return false;    }    printf("发送消息: %s\n", strSendBuf.c_str());    char recvBuf[1024] = { 0 };    iRet = recv(m_Scoket, recvBuf, sizeof(recvBuf), 0);    if (iRet == -1)    {        printf("接受消息超时\n");        return false;    }    string recvMsg = string(recvBuf);    if (recvMsg.find(to_string(MsgType)) == string::npos)        return false;    strRecvMsg = string(recvBuf);    return true;}

测试程序:

#include 
#include "TcpSocket.h"int main(){ TcpSocket client; bool isRet = client.SocketInit(); if (!isRet) return 0; isRet = client.CreatSocket("10.1.1.66", 2345); if (isRet) { while(1) { string strRecv = string(); client.SendMsg(1, string("Hello"), strRecv, 5); printf("接受消息: %s\n", strRecv.c_str()); Sleep(200); } } getchar(); return 0;}

  以上是个人拙见, 若有更好的方法请指教小弟, 谢谢! 谢谢! 谢谢!

转载于:https://www.cnblogs.com/hul201610101100/p/9989729.html

你可能感兴趣的文章
SQL函数——LENGTH()和LENGTHB()
查看>>
vim - manual -个人笔记
查看>>
详解Javascript中prototype属性(推荐)
查看>>
angularjs实现首页轮播图
查看>>
Git 对象 和checkout 和stash的笔记
查看>>
团队项目总结2-服务器通信模型和顺序图
查看>>
hdu 1085 Holding Bin-Laden Captive!
查看>>
[周记]8.7~8.16
查看>>
递归定义
查看>>
kindeditor 代码高亮设置
查看>>
图的邻接表存储
查看>>
2018 leetcode
查看>>
PHP中获取当前页面的完整URL
查看>>
Chapter 4 Syntax Analysis
查看>>
vi/vim使用
查看>>
讨论Spring整合Mybatis时一级缓存失效得问题
查看>>
Maven私服配置Setting和Pom文件
查看>>
Xcode10 library not found for -lstdc++ 找不到问题
查看>>
Mysql 8.0.13如何重置密码
查看>>
发布功能完成
查看>>