zoukankan      html  css  js  c++  java
  • 基于TCP(面向连接)的Socket编程

    基于TCP(面向连接)的Socket编程

    一、客户端:

    1、打开一个套接字(Socket);

    2、发起连接请求(connect);

    3、如果连接成功,则进行数据交换(read、write、send、recv);

    4、数据交换完成,关闭连接(shutdown、close);

    二、服务器端:

    1、打开一个套接字(Socket);

    2、将套接字绑定到服务器地址上(bind);

    3、指定套接字为服务器套接字(listen),做好连接请求准备;

    4、等待连接请求(connect);

    5、如果连接请求到,则连接建立,进行数据交换(read、write、send、recv);

    6、数据交换完成,关闭连接(shutdown、close);

    基于UDP(面向无连接)的Socket编程

    一、客户端服务器端:

    1、打开一个套接字(Socket);

    2、将套接字绑定到指定的服务器地址和端口上(bind);

    3、进行数据交换(read、write、send、recv);

    4、数据交换完成,关闭连接(shutdown、close);

    三、MFC对Socket的支持:

    1、创建CAsyncSocket对象;

    2、发送接收数据报(SendTo、RecvFrom);

    3、连接服务器(Connect);

    4、接收连接(Listen);

    5、发送和接收流式数据(Send、Receive);

    6、关闭套接字(Close);

    7、差错处理(GetLastError)。

    四、实例:网络聊天工具

         客户端:

    1、。。。。

    2、利用类向导重载CAsyncSocket类,生成新的MySocket类。。

    3、利用类向导重载CAsyncSocket的OnReceive(int nErrorCode)和OnSend(int nErrorCode)、OnConnect(int nErrorCode)函数。

    void MySocket::OnReceive(int nErrorCode)

    {

           // TODO: Add your specialized code here and/or call the base class

           //获取对话框指针

           CTestApp*pApp=(CTestApp*)AfxGetApp();

           CTestDlg*pDlg=(CTestDlg*)pApp->m_pMainWnd;

           //往编辑框中插入消息

           char *pbuf=new char[4096];

           int ibufsize=4096;

           int ircvd;

           CString strrecvd;

           ircvd=Receive(pbuf,ibufsize);

           if(ircvd==SOCKET_ERROR)

           {

                  pDlg->MessageBox("SOCKET_ERROR");

           }

           else

           {

                  pbuf[ircvd]=NULL;      

                  pDlg->m_recmsg+="服务器:";

                  pDlg->m_recmsg+=pbuf;     

                  pDlg->m_recmsg+=" ";

                  pDlg->RefreshScreen();

           }

           delete pbuf;

           CAsyncSocket::OnReceive(nErrorCode);

    }

    void MySocket::OnSend(int nErrorCode)

    {

           // TODO: Add your specialized code here and/or call the base class

           CAsyncSocket::OnSend(nErrorCode);

    }

    void MySocket::OnConnect(int nErrorCode)

    {

           // TODO: Add your specialized code here and/or call the base class

           CTestApp*pApp=(CTestApp*)AfxGetApp();

           CTestDlg*pDlg=(CTestDlg*)pApp->m_pMainWnd;

           int iResult=nErrorCode;

           CString buffer;

           int namelen;

           if(iResult!=0)

           {

                  buffer.Format("连接服务器失败。 ");

                  pDlg->m_recmsg+=buffer;

           }

           else

           {

                  namelen=sizeof(sockaddr_in);

                  buffer.Format("成功连接到服务器 %s:%d. ",pDlg->m_ipstr,pDlg->m_port);

                  pDlg->m_recmsg+=buffer;

                  pDlg->GetDlgItem(IDC_SEND)->EnableWindow(TRUE);

                  pDlg->GetDlgItem(IDOK)->EnableWindow(TRUE);

           }

           pDlg->RefreshScreen();

           CAsyncSocket::OnConnect(nErrorCode);

    }

    4、在C*Dlg类中

    头文件中:

    #include "MySocket.h"

           MySocket m_socket;

           CString m_ipstr;

    .CPP文件中:

    void CTestDlg::OnSend()

    {

           // TODO: Add your control notification handler code here

           int ilen;

           int isent;

           UpdateData(TRUE);

           if(m_msg!="")

           {

                  ilen=m_msg.GetLength ();

                  isent=m_socket.Send(LPCTSTR(m_msg),ilen);

                  if(isent==SOCKET_ERROR)

                  {

                         MessageBox("连接失败,请重试!");

                  //     connect=false;

                  }

                  else

                  {

                         m_recmsg+="客户机:"+m_msg;

                         m_recmsg+=" ";

                         UpdateData(FALSE);

                  }

           }

    }

    void CTestDlg::RefreshScreen()

    {

           UpdateData(false);

    }

    void CTestDlg::OnConnect()

    {

           if (!AfxSocketInit())

           {

                  AfxMessageBox("IDP_SOCKETS_INIT_FAILED");

                  return ;

           }

           GetDlgItemText(IDC_IPADDRESS1,m_ipstr);

           m_socket.m_hSocket=INVALID_SOCKET;

           UpdateData(true);

           BOOL flag=m_socket.Create();

           if(!flag)

           {

                  AfxMessageBox("SOCKET ERROR");

                  return;

           }

           m_socket.Connect(m_ipstr,m_port);

    }

    void CTestDlg::OnOK()

    {

           // TODO: Add extra validation here

           m_socket.Close();

           CDialog::OnOK();

    }

              服务器端:

    1、。。。。

    2、利用类向导重载CAsyncSocket类,生成新的MySocket类。。

    3、利用类向导重载CAsyncSocket的OnReceive(int nErrorCode)和OnSend(int nErrorCode)函数。

    void MySocket::OnReceive(int nErrorCode)

    {

           // TODO: Add your specialized code here and/or call the base class

           CTestApp*pApp=(CTestApp*)AfxGetApp();

           CTestDlg*pDlg=(CTestDlg*)pApp->m_pMainWnd;

           //往列表框中插入消息

           char *pbuf=new char[4096];

           int ibufsize=4096;

           int ircvd;

           CString strrecvd;

           ircvd=Receive(pbuf,ibufsize);

           if(ircvd==SOCKET_ERROR)

           {

                  pDlg->MessageBox("SOCKET_ERROR");

           }

           else

           {

                  pbuf[ircvd]=NULL;

                  pDlg->m_msg+="客户机:";

                  pDlg->m_msg+=pbuf;

                  pDlg->m_msg+=" ";

                  pDlg->RefreshScreen();

           }

           delete pbuf;

           CAsyncSocket::OnReceive(nErrorCode);

    }

    void MySocket::OnSend(int nErrorCode)

    {

           // TODO: Add your specialized code here and/or call the base class

           CAsyncSocket::OnSend(nErrorCode);

    }

    4、新建MyServerSocket类,并添加MySocket * m_socket;即接收请求后的套接字指针。

           MySocket * m_socket;

    void CMyServerSocket::OnAccept(int nErrorCode)

    {

           // TODO: Add your specialized code here and/or call the base class

           CTestApp*pApp=(CTestApp*)AfxGetApp();

           CTestDlg*pDlg=(CTestDlg*)pApp->m_pMainWnd;

           //显示连接消息

           pDlg->m_msg="客户机连接到服务器";

           pDlg->m_msg+=" ";

           pDlg->RefreshScreen();

           pDlg->GetDlgItem(IDC_SEND)->EnableWindow(TRUE);

           pDlg->GetDlgItem(IDOK)->EnableWindow(TRUE);

           MySocket* psocket=new MySocket();

           if(Accept(*psocket))

           {

                  psocket->AsyncSelect(FD_READ);

                  m_socket=psocket;

           }

           else

           {

                  delete psocket;

           }    

           CAsyncSocket::OnAccept(nErrorCode);

    }

    5、C*Dlg类中

    void CTestDlg::RefreshScreen()

    {

           UpdateData(false);

    }

    void CTestDlg::OnListen() //创建服务器

    {

           // TODO: Add your control notification handler code here

           UpdateData(true);

           if (!AfxSocketInit())

           {

                  AfxMessageBox("IDP_SOCKETS_INIT_FAILED");

                  return ;

           }

           BOOL flag=m_serversocket.Create(m_port);

           if(!flag)

           {

                  AfxMessageBox("SOCKET ERROR");

                  return;

           }

           flag=m_serversocket.Listen(1);

           if(!flag)

           {

                  AfxMessageBox("SOCKET ERROR");

                  return;

           }

           SetDlgItemText(IDC_LISTEN,"正在监听");

    }

    void CTestDlg::OnSend()

    {

           // TODO: Add your control notification handler code here

           int ilen;

           int isent;

           UpdateData(TRUE);

           if(m_sendmsg!="")

           {

                  ilen=m_sendmsg.GetLength ();

                  isent=m_serversocket.m_socket->Send(LPCTSTR(m_sendmsg),ilen);

                  if(isent==SOCKET_ERROR)

                  {

                         MessageBox("连接失败,请重试!");

                  }

                  else

                  {

                         m_msg+="服务器:"+m_sendmsg;

                         m_msg+=" ";

                         UpdateData(FALSE);

                  }

           }

    }

    void CTestDlg::OnOK()

    {

           // TODO: Add extra validation here

           m_sendmsg="服务器退出";

           UpdateData(false);

           OnSend();

           m_serversocket.Close();

           CDialog::OnOK();

    }

  • 相关阅读:
    PAT (Basic Level) Practise 1013 数素数
    PAT (Basic Level) Practise 1014 福尔摩斯的约会
    codeforces 814B.An express train to reveries 解题报告
    KMP算法
    rsync工具
    codeforces 777C.Alyona and Spreadsheet 解题报告
    codeforces 798C.Mike and gcd problem 解题报告
    nginx + tomcat多实例
    MongoDB副本集
    指针的艺术(转载)
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4243469.html
Copyright © 2011-2022 走看看