Windows Socket Sockets: MFC Socket Programming

network terminology


Synchronous: refers to the communication mode in which the sender sends the data and waits for the response from the receiver before sending the next data packet.
Asynchronous: refers to the communication in which the sender sends the next data packet without waiting for the receiver to respond. Blocking
: When calling a function, it will not return until the function completes the operation; otherwise, it will always block on the call.
Non-blocking: When calling an operation, it will return immediately regardless of whether the operation is successful or not, and will not hang on the operation.

1. CAsyncSocket class


Provides an event-based I/O asynchronous model


1.create


This method is used to create a Windows socket and attach it to the CAsyncSocket class object
BOOL Create(UINT nSocketPort=0,int nSocketType=SOCK_STREAM,long IEvent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,LPCTSTR lpszSocketAddress =NULL);
nSocketPort: socket port, if it is 0, the system automatically selects a port
nSocketType: socket type, if SOCK_STREAM=stream socket, SOCK_DGRAM=datagram socket
IEvent: socket can Processed network events
FD_READ: Triggered when there is data in the socket to be read
FD_WRITE: Triggered when data is written to the socket
FD_OOB: Triggered when out-of-band data is
received FD_ACCEPT: When a connection request is received Trigger event
FD_CONNECT: Trigger event when connection is complete
FD_CLOSE: Trigger event when socket is closed
lpszSocketAddress: IP address of the socket


2.GetLastError


This method is used to get the status information of the last operation failure
static int GetLastError();


3.GetPeerName


This method is used to get the IP address information in the socket connection
BOOL GetPeerName(CString&rPeerAddress,UINT&rPeerPort);
BOOL GetPeerName(SOCKADDR*lpSockAddr,int*lpSockAddrLen);
rPeerAddress: used to receive the IP address returned by the function
rPeerPort: used to record the port No.
lpSockAddr: a socketaddr structure pointer, used to record the socket name
lpSockAddrLen: used to determine the size of lpSocketAddr


4.Accept


This method is used to accept the client's connection
virtual BOOL Accept(CAsyncSocket&rConnectedSocket,SOCKADDR*lpsockAddr=NULL,int*lpSockAddrLen=NULL);
rConnectedSocket: the socket reference corresponding to the current connection
lpSockAddr: a sockaddr structure pointer, used to record the socket Address
lpSockAddrLen: used to determine the size of lpsockaddr


5.bind


This method is used to bind the IP address and port number to the socket
BOOL Bind(UINT nSocketPort,LPCTSTR lpszSocketAddress=NULL);
BOOL Bind(const SOCKADDR*lpSockAddr,int nSockAddrLen);
nSocketport: socket port
lpszSocketAddress:IP Address
lpSockADdr: a sockaddr structure pointer
nSockAddrLen: used to determine the size of lpsockAddr

6.connect

This method is used to send a connection request
BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
BOOL Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
lpszHostAddress: the IP address or URL
of the host nHostPort: the port of the host
lpSockADdr: a pointer to a sockaddr structure
nSockAddrLen : used to determine the size of lpsockAddr

7.close

This method is used to close the socket
virtual void Close();

8.Listen

This method is used to put the socket in listening mode
BOOL Listen(int nConnectionBacklog=5);
nConnectionBacklog: maximum queue length waiting for connections

9.receive

This method is used to receive data in streaming sockets
virtual int Receive(void* lpBuf, int nBuflen, int nFlags=0);
lpBuf: buffer to receive data
nBufLen: determine the length of the buffer
nFlags: determine the call of the function Mode, MSG_PEEK=represents viewing incoming data, data is copied to the receive buffer, but not removed from the input queue; MSG_OOB=processes out-of-band data.

10.ReceiveFrom

This method is used to receive data from the packet socket
int ReceiveFrom(void*lpBuf,int nBufLen,CString&rSocketAddress,UINT&rSocktPort,int nFlags=0);
int RecerveFrom(void *lpBuf,int nBufLen,SOCKADDR* lpSockAddr,int *lpSockAddrLen ,int Flags=0);
lpBuf: buffer for receiving data
nBufLen: buffer size
rSocketAddress: destination (IP address) for receiving datagrams
rSocketPort: used to record the port number
lpSockAddr: a pointer to a sockaddr structure for Record socket address information
lpSockAddrLen: used to determine the size of lpSockAddr
nFlags: function calling mode

11.send


This method is used to send data to the streaming socket
virtual Send(const void* lpBuf, int nBufLen, int nFlags=0);
lpBuf: buffer to send data
nBufLen: buffer size
nFlags: function call method

12.sendTo


This method is used to send data on stream socket or packet socket
int SendTo(const void*lpBuf,int nBuflen,UINT nHostPort,LPCTSTR lpszHostAddress=NULL,int nFlags=0);
int Sendto(const void* lpBuf,int nBufLen,const SOCKADDR* lpSockAddr,int nSockAddrLen,int nFlags=0);
lpBuf: buffer to send data
nBufLen: buffer size
nHostPort: host port number
lpszHostAddress: host address
lpSockAddr: a sockaddr structure pointer
nSockAddrLen: lpsockAddr The size of
nFlags: how the function is called


13.shutDown


This method is used to disconnect the sending or receiving of data on the socket.
BOOL ShutDown(int nHow=sends);
nHow: used to determine the behavior of the function, 0 means not allowed to receive, 1 means not allowed to send, 2 means not allowed receive and send

14.OnAccept

This event is triggered when the socket receives a connection request
virtual void OnAccept(int nErrorCode);
nErrorCode: error code

15.OnClose

The event is fired when the socket is closed
virtual void OnClose(int nErrorCode);

16.OnConnect

This event is triggered when the socket is connected
virtual OnConnect(int nErrorCode);

17.OnReiceive

This event is triggered when the socket has data received
virtual OnReiceive(int nErrorCode);

18.Unsend

This event is triggered when the socket sends data
virtual Onsend(int nErrorCode);

2. CSocket class


The CSocket class is derived from the CAsyncSocket class, which encapsulates socket functions at a higher level and provides synchronization technology.

1.create

This method is used to create a Windows socket and attach it to the CSocket class object
BOOL Create(UINT nSocketPort=0,int nSocketType=SOCK_STREAM ,LPCTSTR lpszSocketAddress=NULL);
nSocketPort: socket port, if 0, The system automatically selects a port
nSocketType: socket type, if SOCK_STREAM=stream socket, SOCK_DGRAM=datagram socket
lpszSocketAddress: socket IP address

2.Attach

This method is used to attach a socket handle to the CSocket class object
BOOL Atach(SOCKET hSocket);
hSocket: socket handle

3.FromHandle

This method obtains the CSocket object pointer according to the socket handle
static CSocket* PASCAL FromHandle(SOCKET hSocket);
hSocket: socket handle
Return value: CSocket object pointer

4.lsBlocking

This method is used to determine whether the socket is in blocking mode
BOOL lsBlocking();
return value: 0=non-blocking, non-0=blocking

5.CancelBlockingCall

This method is used to cancel the blocking mode of the socket
void CancelBlockingCall();

Third, the client implementation process


1. Create a dialog box, project client


2. Initialize the socket in the InitInstance method

 

[cpp] view plain copy

  1. BOOL CClientApp::InitInstance()  
  2. {  
  3.  WSADATA wsd; //Define the WSADATA object  
  4.  WSAStartup(MAKEWORD(2,2),&wsd); //Initialize the socket  
  5. }  


 

 

3. Derive a subclass CClientSocket from the CSocket class, and add the m_pDialog member to this class

 

[cpp] view plain copy

  1. CClientDlg *m_pDialog;//Add member variables  


 

 

4. Add the SetDialog method in CClientSocket for social member variables

[cpp] view plain copy

  1. void CClientSocket::SetDialog(CClientDlg *pDialog)  
  2. {  
  3.  m_pDialog = pDialog;//Set member variables  
  4. }  



5. Rewrite the OnReceive method of the CClientSocket class and call this method when the socket has data to receive

[cpp] view plain copy

  1. void CClientSocket::OnReceive(int nErrorCode)   
  2. {  
  3.  CSocket::OnReceive(nErrorCode);  
  4.  if (m_pDialog != NULL)//Determine whether the member variable is empty  
  5.   m_pDialog->ReceiveText();//Call the ReceiveText method of the dialog class to receive data  
  6. }  



6. Add the following member variables to the dialog box

[cpp] view plain copy

  1. CClientSocket m_SockClient;//Define socket member variables  
  2. CString m_Name;//Define a string variable  



7. Add the ReceiveText method to the dialog class to receive data

[cpp] view plain copy

  1. void CClientDlg::ReceiveText()  
  2. {  
  3.  char buffer[BUFFERSIZE];//Define the buffer for receiving data  
  4.  int len ​​= m_SockClient.Receive(buffer,BUFFERSIZE);//Start receiving data  
  5.  if (len != -1)  
  6.  {  
  7.   buffer[len] = '\0';//Set the end marker  
  8.   m_List.AddString(buffer);//Add the received information to the list  
  9.  }  
  10. }  



8. Create the socket when the dialog is initialized

 

[cpp] view plain copy

  1. m_SockClient.Create();//Create a socket  
  2. m_SockClient.SetDialog(this);//Set the member variables of the socket  


9. Process the "Login" button and start logging into the server

 

[cpp] view plain copy

  1. void CClientDlg::OnLogin()   
  2. {  
  3.  CString strIP, strPort;//Define two string variables  
  4.  UINT port ;//Define an integer port variable  
  5.  m_ServerIP.GetWindowText(strIP);//Get server IP  
  6.  m_NickName.GetWindowText(m_Name);//Get the user's nickname  
  7.  m_ServerPort.GetWindowText(strPort);//Get the port  
  8.  if (strIP.IsEmpty() || strPort.IsEmpty() || m_Name.IsEmpty())  
  9.  {  
  10.   MessageBox("Please set server information","Prompt");  
  11.   return;  
  12.  }  
  13.  port = atoi(strPort);//Convert port string to integer  
  14.  if (m_SockClient.Connect(strIP,port))//Start connecting to the server  
  15.  {  
  16.   MessageBox("Connect to the server successfully!","Prompt");  
  17.   CString str;  
  18.   str.Format("%s----->%s",m_Name,"Enter the chat room");  
  19.   m_SockClient.Send(str.GetBuffer(0),str.GetLength());//Send data to the server, and then forward it by the server  
  20.  }  
  21.  else  
  22.  {  
  23.   MessageBox("Failed to connect to server!","Prompt");  
  24.  }  
  25. }  


 


10. Process the "Send" button, send data to the server, and the server forwards the data

 

 

[cpp] view plain copy

  1. void CClientDlg::OnSendText()   
  2. {  
  3.  CString strText, strInfo;//Define two string variables  
  4.  m_Text.GetWindowText(strText);//Get the sent content  
  5.  if (!strText.IsEmpty() && !m_Name.IsEmpty())  
  6.  {  
  7.   strInfo.Format("%s says: %s",m_Name,strText);//Set the text to send  
  8. // start sending data  
  9.   int len = m_SockClient.Send(strInfo.GetBuffer(strInfo.GetLength()),strInfo.GetLength());  
  10.  }  
  11. }  

 

Fourth, the server implementation process

 

1. Create a dialog box, project Server

 

2. Initialize the socket in the InitInstance method

 

[cpp] view plain copy

  1. BOOL CClientApp::InitInstance()  
  2. {  
  3.   //Initialize the socket  
  4.  WSADATA wsd;  
  5.  AfxSocketInit(&wsd);  
  6. }  

 


3. Derive a subclass CServerSocket from the CSocket class, and add the m_pDlg member to this class

 

 

[cpp] view plain copy

  1. CServerDlg *m_pDlg;//Add member variables  

 


4. Add the SetDialog method in CServerSocket for social member variables

 

 

[cpp] view plain copy

  1. void CServerSocket::SetDialog(CServerDlg *pDialog)  
  2. {  
  3.  m_pDlg= pDialog;//Set member variables  
  4. }  

 


5. Rewrite the OnAccept method of the CServerSocket class to accept the connection when the socket has a connection request

 

 

[cpp] view plain copy

  1. void CServerSocket::OnAccept(int nErrorCode)   
  2. {  
  3.  CSocket::OnAccept(nErrorCode);  
  4.  if (m_pDlg)  
  5.   m_pDlg->AcceptConnect();  
  6. }  

 

6. Derive a new class CClientSocket from the CSocket class again, and define the member variable m_pDlg in this class

 

[cpp] view plain copy

  1. CServerDlg* m_pDlg;  


7. Add the SetDlialog function to the CClientSocket class and assign a value to the m_pDlg member variable

 

 

[cpp] view plain copy

  1. void CClientSocket::SetDialog(CServerDlg* pDialog)  
  2. {  
  3.  m_pDlg = pDialog;  
  4. }  

 


8. Rewrite the OnReceive method of the CClientSocket class to receive data when the socket has data

 

[cpp] view plain copy

  1. void CClientSocket::OnReceive(int nErrorCode)   
  2. {  
  3.  CSocket::OnReceive(nErrorCode);  
  4.  if(m_pDlg)  
  5.  {  
  6.   m_pDlg->ReceiveData(*this);  
  7.  }  
  8. }  

 


9. Add the following member variables to the dialog class

 

[cpp] view plain copy

  1. CPtrList m_socketlist;//Define the socket list container  
  2. CServerSocket m_ServerSock;//Define socket  

 


10. Add the AcceptConnect method to the dialog class to accept the connection from the client

 

[cpp] view plain copy

  1. void CServerDlg::AcceptConnect()  
  2. {  
  3.  CClientSocket* psocket = new CClientSocket();//Create a socket  
  4.  psocket->SetDialog(this);//Set socket member variables  
  5.  if (m_ServerSock.Accept(*psocket))//Accept socket connection  
  6.   m_socketlist.AddTail(psocket);//Add the socket to the list container  
  7.  else  
  8.   delete psocket;//Connection failed, release the socket  
  9. }  

 


11. Add the ReceiveData method to the dialog class to receive data

[cpp] view plain copy

  1. void CServerDlg::ReceiveData(CSocket &socket)  
  2. {  
  3.  char bufferdata[BUFFERSIZE];  
  4.  int len ​​= socket.Receive(bufferdata,BUFFERSIZE);//Start receiving data  
  5.  if (len != -1)//Determine whether data is received  
  6.  {  
  7.   bufferdata[len] = 0;//Set data end marker  
  8.   POSITION pos = m_socketlist.GetHeadPosition();//Get the first position of the container list  
  9.   while (pos != NULL)//traverse the container list  
  10.   {//Get the specified socket in the container list  
  11.    CClientSocket* socket = (CClientSocket*)m_socketlist.GetNext(pos);  
  12.    if (socket != NULL)//Determine whether the socket is empty  
  13.     socket->Send(bufferdata,len);//Send data to the socket  
  14.   }  
  15.  }  
  16. }  



 
12. Process the "Settings" button, create and start listening sockets

 

[cpp] view plain copy

  1. void CServerDlg::OnConfig()   
  2. {  
  3.  m_ServerSock.SetDialog(this);//Set socket member variables  
  4.  CString strPort,strIP;//Define two string variables  
  5.  m_ServerPort.GetWindowText(strPort);//Get the port string  
  6.  m_ServerIP.GetWindowText(strIP);//Get the service IP  
  7.  if (!strPort.IsEmpty() && !strIP.IsEmpty())  
  8.  {  
  9.   UINT port = atoi(strPort);  
  10.   m_ServerSock.Create(port,SOCK_STREAM,strIP);//Create a socket  
  11.   BOOL ret = m_ServerSock.Listen();//Put the socket in listening mode  
  12.   if (ret)  
  13.    MessageBox("Set successfully!","Prompt");  
  14.  }  
  15. }  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325022347&siteId=291194637