基於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+="\r\n";

              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("連接服務器失敗。\r\n");

              pDlg->m_recmsg+=buffer;

       }

       else

       {

              namelen=sizeof(sockaddr_in);

              buffer.Format("成功連接到服務器 %s:%d.\r\n",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+="\r\n";

                     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+="\r\n";

              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+="\r\n";

       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+="\r\n";

                     UpdateData(FALSE);

              }

       }

}

 

 

void CTestDlg::OnOK()

{

       // TODO: Add extra validation here

       m_sendmsg="服務器退出";

       UpdateData(false);

       OnSend();

       m_serversocket.Close();

       CDialog::OnOK();

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM