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 = 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 <stdio.h>
#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;
}

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

posted @ 2018-11-20 16:28  Software_hul  阅读(5577)  评论(0编辑  收藏  举报