vs tcp的使用

本文以mfc 对话框为作为前端显示,实现tcp的连接。

1 在OnInitDialog函数里加上下面的代码,调用WSAStartup,看网上示例很多都没提到。

WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

如果不调用WSAStartup,bind() 函数会返回,GetLastError() 后显示原因。

               

 

2 程序的最后要释放资源

WSACleanup();

 

3 服务端 bind listen

tcp的服务端使用bind函数监听端口。

定义几个成员变量。

SOCKET m_SOCKET_listen;
sockaddr_in m_sockaddr_listen;


SOCKET m_SOCKET_toClient;
sockaddr_in m_sockaddr_toClient;

绑定监听端口

void CMFCApp_TcpDemo1Dlg::OnBnClickedBtnBindLocalPort()
{
    UpdateData(TRUE);
    // 初始化地址端口信息
    m_sockaddr_listen.sin_family = AF_INET;
    m_sockaddr_listen.sin_port = htons(m_n_localPort);
    m_sockaddr_listen.sin_addr.S_un.S_addr = INADDR_ANY;
    // 初始化socket
    m_SOCKET_listen = ::socket(AF_INET, SOCK_STREAM, 0);    
// 绑定、监听 if (bindAndListen(m_SOCKET_listen, m_sockaddr_listen) == SOCKET_ERROR) { DWORD dwError = GetLastError(); UpdateTcpInfoNextLine_FormatInt(_T("监听端口失败,Error Code : [%d]"), dwError); return; } UpdateTcpInfoNextLine(_T("绑定端口并监听成功!")); ::WSAAsyncSelect(m_SOCKET_listen, this->m_hWnd, WM_SOCKET, FD_ACCEPT|FD_READ); }
int CMFCApp_TcpDemo1Dlg::bindAndListen(const SOCKET socket, const sockaddr_in addr)
{
    if (::bind(socket, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
        return SOCKET_ERROR;
    if (::listen(socket, 5) == SOCKET_ERROR)
        return SOCKET_ERROR;
    return 0;
}

处理监听消息

#define WM_SOCKET_LISTEN WM_USER + 200

// 方法声明
afx_msg LRESULT OnSocketListen(WPARAM wParam, LPARAM lParam);

// 消息映射    
ON_MESSAGE(WM_SOCKET_LISTEN,&CMFCApp_TcpDemo1Dlg::OnSocketListen)
// 方法实现 LRESULT CMFCApp_TcpDemo1Dlg::OnSocketListen(WPARAM wParam, LPARAM lParam) { CString str13; switch (lParam) { case FD_ACCEPT: { int size = sizeof(m_sockaddr_toClient); m_SOCKET_toClient = ::accept(m_SOCKET_listen, (sockaddr*)&m_sockaddr_toClient, &size); m_n_connectCnt = m_n_connectCnt + 1; UpdateTcpInfoNextLine_FormatInt("连接数%d", m_n_connectCnt); CString my_Str_msg; my_Str_msg.AppendFormat(_T("%s登录"), ::inet_ntoa(m_sockaddr_toClient.sin_addr)); UpdateTcpInfoNextLine(my_Str_msg); } break; case FD_READ: { char my_c_rcv[100] = {0}; CString my_Str_msg; ::recv(m_SOCKET_toClient, my_c_rcv, 100, 0); my_Str_msg += (LPCTSTR)::inet_ntoa(m_sockaddr_toClient.sin_addr); my_Str_msg += ":"; my_Str_msg += (LPCTSTR)my_c_rcv; UpdateTcpInfoNextLine(my_Str_msg); } break; } return true; }

 

 4 客户端

 连接远程服务器

void CMFCApp_TcpDemo1Dlg::OnBnClickedBtnConnect()
{
    // 指定远程客户端的连接信息
    CString str = _T("127.0.0.1");
    UpdateData(TRUE);
    m_sai_destClient.sin_family = AF_INET;
    m_sai_destClient.sin_addr.S_un.S_addr = inet_addr(str.GetBuffer(1));
    m_sai_destClient.sin_port = htons(m_n_destPort);
    m_SOCKET = ::socket(AF_INET, SOCK_STREAM, 0);    
    if (::connect(m_SOCKET, (sockaddr*)&m_sai_destClient, sizeof(m_sai_destClient)) != SOCKET_ERROR)
    {
        UpdateTcpInfoNextLine(_T("连接成功!"));
     ::WSAAsyncSelect(m_SOCKET, this->m_hWnd, WM_SOCKET_CLIENT, FD_READ); }
else { CString str; DWORD dwError = GetLastError(); str.Format(_T("连接失败,Error Code : [%d]"), dwError); char szError[256]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, 0, szError, sizeof(szError), NULL); UpdateTcpInfoNextLine(str + szError); } }

 

发送数据

void CMFCApp_TcpDemo1Dlg::OnBnClickedBtnSend()
{
    UpdateData(TRUE);
    int sendSize = ::send(m_SOCKET, m_Str_send.GetBuffer(1), m_Str_send.GetLength(), 0);
    UpdateTcpInfoNextLine_FormatInt(_T("sendSize, %d"), sendSize);
}

 接收数据,每次给服务端发送数据之后,服务端会返回客户端的内容。

在客户端connect之后,绑定消息映射。

::WSAAsyncSelect(m_SOCKET, this->m_hWnd, WM_SOCKET_CLIENT, FD_READ); (上面的代码已经绑定了),窗口消息与函数绑定的代码和服务端类似。

下面是客户端接收信息的方法。

LRESULT CMFCApp_TcpDemo1Dlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
    switch (lParam)
    {
    case FD_READ:
        {
            char my_c_rcv[100] = {0};
            CString my_Str_msg(_T("server port: "));
            ::recv(m_SOCKET, my_c_rcv, 100, 0);
            my_Str_msg += (LPCTSTR)::inet_ntoa(m_sai_destClient.sin_addr);
            my_Str_msg += ", server: ";
            my_Str_msg += (LPCTSTR)my_c_rcv;

            UpdateTcpInfoNextLine(my_Str_msg);
        }
        break;

    default:
        break;

    }
    return true;
}
posted @ 2021-05-27 14:56  卡卡什么卡  阅读(179)  评论(0编辑  收藏  举报