廢話不多說, 直入主題, 我們在寫客戶單的時候希望在哪里發消息出去,然后在哪里返回消息(同步), 然后繼續往下運行-, 而不是在這里發送了一個消息給服務端, 在另一個地方接受消息(異步) , 也不知道等多久, 才收到消息, 等收到消息在通知發送消息的地方, 讓程序繼續往下運行, 這樣想想異步實在太麻煩了,
實現同步的思想: 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; }
以上是個人拙見, 若有更好的方法請指教小弟, 謝謝! 謝謝! 謝謝!