zoukankan      html  css  js  c++  java
  • C++ 简单封装socket类包含TCP和UDP基本通信能力

    类名:TSocket

    文件包含:TSocket.cpp、TSocket.h
    使用方法:
    1、在对话框头文件包含TSocket.h
    #include "TSocket.h"
     
    2、定义变量
    TSocket m_TSocket;
     
    3、TSocket类函数功能介绍:
    LoadSocket():加载SOCKET库
    CreateSocketSer(TRUE):创建SOCKET,TRUE为TCP,FALSE为UDP
    BingSocket():绑定IP和端口,有默认值
    Start(precvPar):precvPar为一个RECVPARAM结构体指针
    SendData(strSend):发送数据函数
     
    4、服务端处理接收到的数据(消息映射、路由)
    afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);
     
    ON_MESSAGE(WM_RECVDATA,OnRecvData)
     
    void CXXXDlg::OnRecvData( WPARAM wParam,LPARAM lParam )
    {
    CString strrecv = (char*)lParam;//得到消息内容
    }
     
    5、稳定性不能保证,仅供参考socket通信原理。。。。。。
     
     
    ****************************************TSocket.h*****************************************
    // TSocket.h: interface for the TSocket class.
    //
    //////////////////////////////////////////////////////////////////////
     
    #if !defined(AFX_TSOCKET_H__ECFF7A02_DCAF_455D_97C3_0C1D465D977B__INCLUDED_)
    #define AFX_TSOCKET_H__ECFF7A02_DCAF_455D_97C3_0C1D465D977B__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
     
    #include
    #pragma comment(lib,"ws2_32.lib")
     
    #define WM_RECVDATA WM_USER+500 //定义接收到数据发出的消息号
    #define MAX_MSG_LEN 1500 //最大的消息长度(MTU)
    #define DEFAULTPORT 1991 //定义默认服务端口
     
    class TSocket;
     
    struct RECVPARAM 
    {
    TSocket* psocket;//指定创建的socket
    HWND hwnd;//指定需要处理接收消息的窗口句柄
    };
     
    class TSocket  
    {
    public:
    TSocket();
    virtual ~TSocket();
     
    public:
    //加载Winsock库
    BOOL LoadSocket();
    BOOL CreateSocketSer(BOOL bMode);//创建socket用于服务器端
    SOCKET CreateSocket(BOOL bMode);//创建socket用于客户端
    BOOL BingSocket(u_long ulIP=0,u_short usPort=DEFAULTPORT);//绑定端口、IP(默认所有IP)
    BOOL Start(RECVPARAM* recvPar);
    BOOL Stop();
    SOCKET GetSocket();//得到当前socket
    CString m_strData;//发出去的数据
     
    BOOL m_bIsRun; //是否继续运行
     
    u_long m_ulLocalIP;//本地IP
    u_short m_usLocalPort;//本地端口
    u_long m_ulRemoteIP;//远程IP
    u_short m_usRemotePort;//远程端口
     
    //发送数据
    DWORD SendData(CString strSend);
    //TCP发送线程
    static DWORD WINAPI TcpSendProc(LPVOID lpParameter);
    //UDP发送线程
    static DWORD WINAPI UdpSendProc(LPVOID lpParameter);
    //TCP发送数据
    DWORD TcpSend();
    //UDP发送数据
    DWORD UdpSend();
     
    private:
    BOOL m_bMode; //通信方式 1--TCP 0--UDP
    SOCKET m_socket;//套接字
    HANDLE m_hRecv; //接收线程的句柄
     
    //TCP接收线程
    static DWORD WINAPI TcpRecvProc(LPVOID lpParameter);
    //UDP接收线程
    static DWORD WINAPI UdpRecvProc(LPVOID lpParameter);
     
    };
     
    #endif // !defined(AFX_TSOCKET_H__ECFF7A02_DCAF_455D_97C3_0C1D465D977B__INCLUDED_)
     
    ****************************************TSocket.h*****************************************
     
    ****************************************TSocket.cpp*****************************************
    // TSocket.cpp: implementation of the TSocket class.
    //
    //////////////////////////////////////////////////////////////////////
     
    #include "stdafx.h"
    #include "TSocket.h"
     
    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif
     
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
     
    TSocket::TSocket()
    {
    m_bMode = FALSE;//UDP
    m_ulRemoteIP = 0;
    m_ulLocalIP = 0;
    }
     
    TSocket::~TSocket()
    {
    //释放Winsock库
    WSACleanup();
    }
     
    BOOL TSocket::LoadSocket()
    {
    //加载Winsock库
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(1,1),&wsa) != 0)
    {
    return FALSE;   //加载失败
    }
    return TRUE;
    }
     
     
    BOOL TSocket::CreateSocketSer(BOOL bMode)
    {
    m_bMode = bMode;
     
    //创建SOCKET
    if (m_bMode)
    {
    m_socket = socket(AF_INET,SOCK_STREAM,0);//TCP流式
    }else
    {
    m_socket = socket(AF_INET,SOCK_DGRAM,0);//UDP方式
    }
     
    return TRUE;
    }
     
     
    SOCKET TSocket::CreateSocket( BOOL bMode )
    {
    m_bMode = bMode;
    SOCKET socketCr;
     
    //创建SOCKET
    if (m_bMode)
    {
    socketCr = socket(AF_INET,SOCK_STREAM,0);//TCP方式
    }else
    {
    socketCr = socket(AF_INET,SOCK_DGRAM,0);//UDP方式
    }
     
    return socketCr;
    }
     
    BOOL TSocket::BingSocket(u_long ulIP,u_short usPort)
    {
    //配置监听地址、绑定监听端口
    SOCKADDR_IN Sersock;//用于服务器的监听SOCKET
    ZeroMemory(&Sersock,sizeof(Sersock));
    if(ulIP==0)
    {
    Sersock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    }else
    {
    Sersock.sin_addr.S_un.S_addr = htonl(ulIP);//IP
    }
    Sersock.sin_family = AF_INET;
    Sersock.sin_port = htons(usPort);//端口号
    int nbind = bind(m_socket,(SOCKADDR *)&Sersock,sizeof(SOCKADDR));
    if (SOCKET_ERROR==nbind)
    {
    closesocket(m_socket);
    return FALSE;
    }
     
    return TRUE;
    }
     
    DWORD WINAPI TSocket::TcpRecvProc( LPVOID lpParameter )
    {
    TSocket* psocket = ((RECVPARAM *)lpParameter)->psocket;
    HWND hwnd = ((RECVPARAM *)lpParameter)->hwnd;
    delete lpParameter;//释放内存
    listen(psocket->m_socket,5);
    SOCKADDR_IN addrClient;
    int len=sizeof(SOCKADDR);
     
    char szrecvbuf[MAX_MSG_LEN];
    char szsendBuf[50];
    ZeroMemory(szrecvbuf,sizeof(szrecvbuf));
    ZeroMemory(szsendBuf,sizeof(szsendBuf));
     
    SOCKET sockSer;
    while(psocket->m_bIsRun)
    {
    //用accept函数接收客户方的连接
    sockSer=accept(psocket->m_socket,(SOCKADDR*)&addrClient,&len);
    if (INVALID_SOCKET==sockSer)
    continue;
     
    sprintf(szsendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
    //在客户方套接字clientSocket上使用send发送数据
    send(sockSer,szsendBuf,strlen(szsendBuf)+1,0);
     
    //接收的数据
    recv(sockSer,szrecvbuf,50,0);
    psocket->m_strData.Format(_T("IP:%s,端口:%d 说:%s"),
    inet_ntoa(addrClient.sin_addr),addrClient.sin_port,szrecvbuf);
    ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)psocket->m_strData.GetBuffer(0));
    //关闭本次连接
    closesocket(sockSer);
     
    //休息100S
    Sleep(100);
    }
     
    //关闭socket
    closesocket(psocket->m_socket);
    return 0;
    }
     
    DWORD WINAPI TSocket::UdpRecvProc( LPVOID lpParameter )
    {
    TSocket* psocket = ((RECVPARAM *)lpParameter)->psocket;
    HWND hwnd = ((RECVPARAM *)lpParameter)->hwnd;
    delete lpParameter;//释放内存
    SOCKADDR_IN sockRecv;
    int nlen = sizeof(SOCKADDR);
    char szrecvbuf[MAX_MSG_LEN];
    ZeroMemory(szrecvbuf,sizeof(szrecvbuf));
    int nrecv;
    while (psocket->m_bIsRun)
    {
    nrecv=recvfrom(psocket->m_socket,szrecvbuf,sizeof(szrecvbuf),0,(SOCKADDR *)&sockRecv,&nlen);
    if (SOCKET_ERROR == nrecv)
    break;
     
    psocket->m_strData.Format(_T("IP:%s,端口:%d 说:%s"),
    inet_ntoa(sockRecv.sin_addr),sockRecv.sin_port,szrecvbuf);
     
    ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)psocket->m_strData.GetBuffer(0));
     
    //休息100S
    Sleep(1000);
    }
     
    //关闭socket
    closesocket(psocket->m_socket);
    CloseHandle(psocket->m_hRecv);
     
    return 0;
    }
     
    BOOL TSocket::Start( RECVPARAM* recvPar )
    {
    m_bIsRun = TRUE;
     
    //创建接收消息的线程
    if (m_bMode)
    {
    m_hRecv = CreateThread(NULL,0,TcpRecvProc,(LPVOID)recvPar,0,NULL);
    }else
    {
    m_hRecv = CreateThread(NULL,0,UdpRecvProc,(LPVOID)recvPar,0,NULL);
    }
     
    return TRUE;
    }
     
    BOOL TSocket::Stop()
    {
    //Kill线程???
    if (m_hRecv!=NULL)
    {
    TerminateThread(m_hRecv,0);
    //关闭socket
    closesocket(m_socket);
    }
     
    m_bIsRun = FALSE;
    return TRUE;
    }
     
    DWORD TSocket::TcpSend()
    {
    if (m_ulRemoteIP==0)
    return -1;
     
    SOCKET SocketSend;
    SocketSend=CreateSocket(TRUE);
    if (SocketSend==INVALID_SOCKET)
    {
    return -1;
    }
     
    SOCKADDR_IN SocketSendIn;
    SocketSendIn.sin_family = AF_INET;
    SocketSendIn.sin_addr.S_un.S_addr = htonl(m_ulRemoteIP);
    SocketSendIn.sin_port = htons(m_usRemotePort);
    char szBuf[50];
     
    //先建立连接
    int nRet = connect(SocketSend,(SOCKADDR*)&SocketSendIn,sizeof(SOCKADDR));
    if (nRet==SOCKET_ERROR)
    {
    return -1;
    }
     
    nRet = recv(SocketSend,szBuf,sizeof(szBuf),0);
    if (nRet==0)//超时
    {
    return -2;
    }
     
    //开始发送数据
    send(SocketSend,m_strData.GetBuffer(0),m_strData.GetLength(),0);
    closesocket(SocketSend);
     
    return 0;
    }
     
    DWORD TSocket::UdpSend()
    {
    if (m_ulRemoteIP==0)
    return -1;
    SOCKET SocketSend;
    SocketSend=CreateSocket(FALSE);
    if (SocketSend==INVALID_SOCKET)
    {
    return -1;
    }
    SOCKADDR_IN SocketSendIn;
    SocketSendIn.sin_family = AF_INET;
    SocketSendIn.sin_addr.S_un.S_addr = htonl(m_ulRemoteIP);
    SocketSendIn.sin_port = htons(m_usRemotePort);
    int nSenlen=m_strData.GetLength()+1;
    sendto(SocketSend,m_strData,nSenlen,0,(SOCKADDR *)&SocketSendIn,sizeof(SOCKADDR));
     
    closesocket(SocketSend);
    return 0;
    }
     
    DWORD TSocket::SendData( CString strSend )
    {
    //保存数据
    m_strData = strSend;
     
    if (m_bMode)
    {
    CreateThread(NULL,0,TcpSendProc,(LPVOID)this,0,NULL);
    }else
    {
    CreateThread(NULL,0,UdpSendProc,(LPVOID)this,0,NULL);
    }
    return 0;
    }
     
    SOCKET TSocket::GetSocket()
    {
    return m_socket;
    }
     
    DWORD WINAPI TSocket::TcpSendProc( LPVOID lpParameter )
    {
    TSocket* pThis = (TSocket*)lpParameter;
    return pThis->TcpSend();
    }
     
    DWORD WINAPI TSocket::UdpSendProc( LPVOID lpParameter )
    {
    TSocket* pThis = (TSocket*)lpParameter;
    return pThis->UdpSend();
    }
     
    ****************************************TSocket.cpp*************
  • 相关阅读:
    Android中的“再按一次返回键退出程序”代码实现
    Android UI编程之自定义控件初步——ImageButton
    21岁,我想当“大帅”
    茑萝改变了我
    茑萝,梦想的加油站
    放弃了我的国企工作
    性能调优之访问日志IO性能优化
    性能调优之提高 ASP.NET Web 应用性能的 24 种方法和技巧
    性能调优之剖析OutOfMemoryError
    老李分享:单元测试检查清单:让测试有效,避免致命错误
  • 原文地址:https://www.cnblogs.com/cy568searchx/p/2845249.html
Copyright © 2011-2022 走看看