首页 > 代码库 > 基于TCP(面向连接)的Socket编程

基于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();

}

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