Socket TCP 客户端 C++动态来接库的封装

注意:
1.先把SDL检查关了,不然inet_addr这个类型会报错
Socket TCP 客户端 C++动态来接库的封装_第1张图片
2.DLL的功能需要借助平台来体现,所以对于初学者建议先建立一个控制台程序来调试,并且辅以较为成熟的工具来调试能达到更好参考的效果,这次我调试的时候是以SocketTool来作为参考的这个网上有资源。

Socket TCP 客户端 C++动态来接库的封装_第2张图片
3.我是借鉴这篇博客的,新建一个C++控制台程序,他有现成的代码,利用SocketTool调试,然后再把代码分块封装就ok了

新建一个工程,具体看我另外一篇博客C++的简单动态链接的创建和引用
Socket TCP 客户端 C++动态来接库的封装_第3张图片
接下来是头文件内容,建议先学会创建和引用再来尝试做这个,虽然这个也很简单。

#pragma once
#include
class _declspec(dllexport) TSocket
{
public:
	bool Client_Connect(std::string strAddr,int nPort,std::string &strError);
	bool Client_DisConnect();
	bool Client_TSockSend(std::string strWord, std::string& strError);
	bool Client_TSockRecv(std::string &strWord,int nTimeout);
};


然后是cpp的内容,只说实现,不谈原理

#include "pch.h"
#include "TSocket.h"
#include "winsock2.h"  
#pragma comment(lib, "ws2_32.lib")  

BOOL RecvLine(SOCKET s, char* buf); //Read the data of a line  

const int BUF_SIZE = 64;
WSADATA wsd; //WSADATA Variable  
SOCKET sHost; //Server socket
SOCKADDR_IN servAddr; //Server Address  
char buf[BUF_SIZE]; //Receiving data buffer area 
char bufRecv[BUF_SIZE];
int retVal; //return value 

bool TSocket::Client_Connect(std::string strAddr, int nPort, std::string& strError)
{
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
    {
        strError = "WSAStartup failed!";
        return false;
    }
    //Create socket  
    sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sHost)
    {
        strError = "socket failed!";
        WSACleanup();//Release socket resource  
        return  false;
    }
    //Set server address 
    servAddr.sin_family = AF_INET;
    const char* cAdd = strAddr.c_str();
    servAddr.sin_addr.s_addr = inet_addr(cAdd);
    servAddr.sin_port = htons((short)nPort);
    int nServAddlen = sizeof(servAddr);
        //Connect Server 
    retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
    if (SOCKET_ERROR == retVal)
    {
        strError = "connect failed!";
        closesocket(sHost); //close socket 
        WSACleanup(); //Release socket resource   
        return false;
    }
    return true;
}

bool TSocket::Client_DisConnect()
{
    closesocket(sHost);
    WSACleanup();
    return true;
}

bool TSocket::Client_TSockSend(std::string strWord, std::string& strError)
{
    //Sending data to the Server 
    ZeroMemory(buf, BUF_SIZE);
    strcpy(buf,strWord.c_str());
    retVal = send(sHost, buf, strlen(buf), 0);
    if (SOCKET_ERROR == retVal)
    {
        //cout << "send failed!" << endl;
        strError = "send failed!";
        closesocket(sHost);
        WSACleanup();
        return false;
    }
    return true;
}

bool TSocket::Client_TSockRecv(std::string& strWord,int nTimeout)//0:永远等待
{ 
    bool bRes;
    ZeroMemory(bufRecv, BUF_SIZE);
    bRes=recv(sHost, bufRecv, BUF_SIZE, 0); // Accepting data from Server,only receiving 5 characters 
    strWord = bufRecv;
    return bRes;
}

编译后即可食用。
给你们看一下我在MFC平台上使用的效果
Socket TCP 客户端 C++动态来接库的封装_第4张图片不知道这样描述准不准确:
因为“接收”函数会阻塞,因此要实现全双工异步这种聊天效果,我选择了使用线程,以下代码是再MFC工程里的。

//这是线程函数
UINT SockRecvThread(LPVOID pParam)
{
	while (true)
	{
		std::string str1;
		CString CstrWord;
		if (g_pMainThis->m_GlobalSysDefine.m_pTSocket->TSockRecv(str1, 0))
		{
			CstrWord = str1.c_str();
			g_pMainThis->m_pDlgTCPClient->strText += (_T("Recv:  ") + CstrWord + _T("\r\n"));
			g_pMainThis->m_pDlgTCPClient->m_RecvEdt.SetWindowTextW(g_pMainThis->m_pDlgTCPClient->strText);
		}
		else
		{
			g_pMainThis->m_pDlgTCPClient->strText += _T("System:  The Server disconnects acttively!");
			g_pMainThis->m_pDlgTCPClient->m_RecvEdt.SetWindowTextW(g_pMainThis->m_pDlgTCPClient->strText);
			return 0;
		}
	}

	return 0;
}


//这是连接按钮
void DlgTCPClient::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strAddr,strError;
	int nPort;
	GetDlgItemText(IDC_EDIT1, strAddr);
	nPort=GetDlgItemInt(IDC_EDIT2);
	std::string str1, str3;
	str1 = CW2A(strAddr.GetString());
	if (!g_pMainThis->m_GlobalSysDefine.m_pTSocket->Connect(str1,nPort,str3))
	{
		strError = str3.c_str();
		strText += (_T("System:  ")+strError+_T("\r\n"));
	}
	else
	{
		m_pThread=::AfxBeginThread(SockRecvThread,NULL);//连接成功后启动线程
		strText += _T("System:  Connect Succesful!\r\n");
	}
	m_RecvEdt.SetWindowTextW(strText);
}


学习笔记,欢迎指正,轻喷(●ˇ∀ˇ●)。。。

你可能感兴趣的:(dll,C/C++字符串,Socket,c++,tcp/ip,开发语言)