⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch20.htm

📁 VC 21天 学习VC 的好东西
💻 HTM
📖 第 1 页 / 共 4 页
字号:
25:         // Server, create a socket bound to the port specified26:         m_sListenSocket.Create(m_iPort);27:         // Listen for connection requests28:         m_sListenSocket.Listen();29:     }30: }</PRE><P>Next, to complete the connection, you'll add the socket event function to thedialog class for the OnAccept and OnConnect event functions. These are the functionsthat your socket class is calling. They don't require any parameters, and they don'tneed to return any result code. For the OnAccept function, which is called for thelistening socket when another application is trying to connect to it, you'll callthe socket object's Accept function, passing in the connection socket variable. Onceyou've accepted the connection, you can enable the prompt and edit box for enteringand sending messages to the other application.</P><P>To add this function to your application, add a member function to the dialogclass (CSockDlg). Specify the function type as void, the declaration as OnAccept,and the access as public. Edit the function, adding the code in Listing 20.7.</P><P><H4>LISTING 20.7. THE CSockDlg OnAccept FUNCTION.</H4><PRE> 1: void CSockDlg::OnAccept() 2: { 3:     // Accept the connection request 4:     m_sListenSocket.Accept(m_sConnectSocket); 5:     // Enable the text and message controls 6:     GetDlgItem(IDC_EMSG)-&gt;EnableWindow(TRUE); 7:     GetDlgItem(IDC_BSEND)-&gt;EnableWindow(TRUE); 8:     GetDlgItem(IDC_STATICMSG)-&gt;EnableWindow(TRUE); 9: }</PRE><P>For the client side, there's nothing to do once the connection has been completedexcept enable the controls for entering and sending messages. You'll also enablethe Close button so that the connection can be closed from the client side (but notthe server side). To add this functionality to your application, add another memberfunction to the dialog class (CSockDlg). Specify the function type as void, the functiondeclaration as OnConnect, and the access as public. Edit the function, adding thecode in Listing 20.8.</P><P><H4>LISTING 20.8. THE CSockDlg OnConnect FUNCTION.</H4><PRE> 1: void CSockDlg::OnConnect() 2: { 3:     // Enable the text and message controls 4:     GetDlgItem(IDC_EMSG)-&gt;EnableWindow(TRUE); 5:     GetDlgItem(IDC_BSEND)-&gt;EnableWindow(TRUE); 6:     GetDlgItem(IDC_STATICMSG)-&gt;EnableWindow(TRUE); 7:     GetDlgItem(IDC_BCLOSE)-&gt;EnableWindow(TRUE); 8: }</PRE><P>If you could compile and run your application now, you could start two copies,put one into listen mode, and then connect to it with the other. Unfortunately, youprobably can't even compile your application right now because your socket classis looking for several functions in your dialog class that you haven't added yet.Add three member functions to the dialog class (CSockDlg). Specify all of them asvoid functions with public access. Specify the first function's declaration as OnSend,the second as OnReceive, and the third as OnClose. You should now be able to compileyour application.</P><P>Once you've compiled your application, start two copies of the application, side-by-side.Specify that one of these two should be the server, and click the Listen button toput it into listen mode. Leave the other as the client and click the Connect button.You should see the connection controls disable and the message sending controls enableas the connection is made, as in Figure 20.6.</P><P><A HREF="javascript:popUp('20fig06.gif')"><B>FIGURE 20.6.</B></A><B> </B><I>Connectingthe two applications.</I></P><BLOCKQUOTE>	<P><HR><STRONG>TIP:</STRONG> Be sure that you have the server application listening before you	try to connect it to the client application. If you try to connect to it with the	client application before the server is listening for the connection, the connection	will be rejected. Your application will not detect that the connection was rejected	because you haven't added any error handling to detect this event.<BR>	<STRONG>TIP:</STRONG> To run these applications and get them to connect, you'll need TCP/IP	running on your computer. If you have a network card in your computer, you may already	have TCP/IP running. If you do not have a network card, and you use a modem to connect	to the Internet, then you will probably need to be connected to the Internet when	you run and test these applications. When you connect to the Internet through a modem,	your computer usually starts running TCP/IP once the connection to the Internet is	made. If you do not have a network card in your computer, and you do not have any	means of connecting to the Internet, or any other outside network that would allow	you to run networked applications, you may not be able to run and test today's applications	on your computer.<HR></BLOCKQUOTE><H3><A NAME="Heading13"></A>Sending and Receiving</H3><P>Now that you are able to connect the two running applications, you'll need toadd functionality to send and receive messages. Once the connection is establishedbetween the two applications, the user can enter text messages in the edit box inthe middle of the dialog window and then click the Send button to send the messageto the other application. Once the message is sent, it will be added to the listbox of sent messages. To provide this functionality, when the Send button is clicked,your application needs to check whether there is a message to be sent, get the lengthof the message, send the message, and then add the message to the list box. To addthis functionality to your application, use the Class Wizard to add a function tothe clicked event of the Send (IDC_BSEND) button. Edit this function, adding thecode in Listing 20.9.</P><P><H4>LISTING 20.9. The CSockDlg OnBsend FUNCTION.</H4><PRE> 1: void CSockDlg::OnBsend() 2: { 3:     // TODO: Add your control notification handler code here 4:     int iLen; 5:     int iSent; 6: 7:     // Sync the controls with the variables 8:     UpdateData(TRUE); 9:     // Is there a message to be sent?10:     if (m_strMessage != &quot;&quot;)11:     {12:         // Get the length of the message13:         iLen = m_strMessage.GetLength();14:         // Send the message15:         iSent = m_sConnectSocket.Send(LPCTSTR(m_strMessage), iLen);16:         // Were we able to send it?17:         if (iSent == SOCKET_ERROR)18:         {19:         }20:         else21:         {22:             // Add the message to the list box.23:             m_ctlSent.AddString(m_strMessage);24:             // Sync the variables with the controls25:             UpdateData(FALSE);26:         }27:     }28: }</PRE><P>When the OnReceive event function is triggered, indicating that a message hasarrived, you'll retrieve the message from the socket using the Receive function.Once you've retrieved the message, you'll convert it into a CString and add it tothe message-received list box. You can add this functionality by editing the OnReceivefunction of the dialog class, adding the code in Listing 20.10.</P><P><H4>LISTING 20.10. THE CSockDlg OnReceive FUNCTION.</H4><PRE> 1: void CSockDlg::OnReceive() 2: { 3:     char *pBuf = new char[1025]; 4:     int iBufSize = 1024; 5:     int iRcvd; 6:     CString strRecvd; 7: 8:     // Receive the message 9:     iRcvd = m_sConnectSocket.Receive(pBuf, iBufSize);10:     // Did we receive anything?11:     if (iRcvd == SOCKET_ERROR)12:     {13:     }14:     else15:     {16:         // Truncate the end of the message17:         pBuf[iRcvd] = NULL;18:         // Copy the message to a CString19:         strRecvd = pBuf;20:         // Add the message to the received list box21:         m_ctlRecvd.AddString(strRecvd);22:         // Sync the variables with the controls23:         UpdateData(FALSE);24:     }25: }</PRE><P>At this point, you should be able to compile and run two copies of your application,connecting them as you did earlier. Once you've got the connection established, youcan enter a message in one application and send it to the other application, as shownin Figure 20.7.</P><P><A HREF="javascript:popUp('20fig07.gif')"><B>FIGURE 20.7.</B></A><B> </B><I>Sendingmessages between the applications.</I></P><P><I></I><H3><A NAME="Heading14"></A>Ending the Connection</H3><P>To close the connection between these two applications, the client applicationuser can click the Close button to end the connection. The server application willthen receive the OnClose socket event. The same thing needs to happen in both cases.The connected socket needs to be closed, and the message sending controls need tobe disabled. On the client, the connection controls can be enabled because the clientcould change some of this information and open a connection to another server application.Meanwhile, the server application continues to listen on the port that it was configuredto listen to. To add all this functionality to your application, edit the OnClosefunction, adding the code in Listing 20.11.</P><P><H4>LISTING 20.11. THE CSockDlg OnClose FUNCTION.</H4><PRE> 1: void CSockDlg::OnClose() 2: { 3:     // Close the connected socket 4:     m_sConnectSocket.Close(); 5:     // Disable the message sending controls 6:     GetDlgItem(IDC_EMSG)-&gt;EnableWindow(FALSE); 7:     GetDlgItem(IDC_BSEND)-&gt;EnableWindow(FALSE); 8:     GetDlgItem(IDC_STATICMSG)-&gt;EnableWindow(FALSE); 9:     GetDlgItem(IDC_BCLOSE)-&gt;EnableWindow(FALSE);10:     // Are we running in Client mode?11:     if (m_iType == 0)12:     {13:         // Yes, so enable the connection configuration controls14:         GetDlgItem(IDC_BCONNECT)-&gt;EnableWindow(TRUE);15:         GetDlgItem(IDC_ESERVNAME)-&gt;EnableWindow(TRUE);16:         GetDlgItem(IDC_ESERVPORT)-&gt;EnableWindow(TRUE);17:         GetDlgItem(IDC_STATICNAME)-&gt;EnableWindow(TRUE);18:         GetDlgItem(IDC_STATICPORT)-&gt;EnableWindow(TRUE);19:         GetDlgItem(IDC_RCLIENT)-&gt;EnableWindow(TRUE);20:         GetDlgItem(IDC_RSERVER)-&gt;EnableWindow(TRUE);21:         GetDlgItem(IDC_STATICTYPE)-&gt;EnableWindow(TRUE);22:     }23: }</PRE><P>Finally, for the Close button, call the OnClose function. To add this functionalityto your application, use the Class Wizard to add a function to the clicked eventfor the Close button (IDC_BCLOSE). Edit the function to call the OnClose function,as in Listing 20.12.</P><P><H4>LISTING 20.12. THE CSockDlg OnBclose FUNCTION.</H4><PRE> 1: void CSockDlg::OnBclose() 2: { 3:     // TODO: Add your control notification handler code here 4:     // Call the OnClose function 5:     OnClose(); 6: }</PRE><P>If you compile and run your application, you can connect the client applicationto the server, send some messages back and forth, and then disconnect the clientby clicking the Close button. You'll see the message-sending controls disable themselvesin both applications, as in Figure 20.8. You can reconnect the client to the serverby clicking the Connect button again and then pass some more messages between thetwo, as if they had never been connected in the first place. If you start a thirdcopy of the application, change its port number, designate it as a server, and putit into listening mode, you can take your client back and forth between the two servers,connecting to one, closing the connection, changing the port number, and then connectingto the other.</P><P><A HREF="javascript:popUp('20fig08.gif')"><B>FIGURE 20.8.</B></A> <I>Closing theconnection between the applications.</I></P><P><I></I><H2><A NAME="Heading15"></A>Summary</H2><P>Today, you learned how you can enable your applications to communicate with othersacross a network or across the Internet by using the MFC Winsock classes. You tooka good look at the CAsyncSocket class and learned how you could create your own descendentclass from it that would provide your applications with event-driven network communications.You learned how to create a server application that can listen for and accept connectionsfrom other applications. You also learned how to build a client application thatcan connect to a server. You learned how to send and receive messages over a socketconnection between two applications. Finally, you learned how to close the connectionand how to detect that the connection has been closed.</P><P><H2><A NAME="Heading16"></A>Q&amp;A</H2><DL>	<DT></DT>	<DD><B>Q How do Internet applications work?</B>	<P>	<DT><B></B></DT>	<DD><B>A</B> Most Internet applications use the same functionality that you created	today. The primary difference is that the applications have a script of messages	that are passed back and forth. The messages consist of a command and the data that	needs to accompany that command. The server reads the command and processes the data	appropriately, sending back a status code to let the client know the success or failure	of the command. If you want to learn more about how Internet applications do this,	several books cover this subject area in detail.	<P>	<DT></DT>	<DD><B>Q How does a server application handle a large number of simultaneous connections	from clients?</B>	<P>	<DT><B></B></DT>	<DD><B>A</B> With a full-strength server, the connection sockets are not declared	as class variables. The server instead uses some sort of dynamic allocation of sockets,	in an array or link-list, to create sockets for the clients as the connection requests	come in. Another approach often taken by servers is to spin off a separate thread	for each connection request. This allows the application to have a single socket	connection per thread, and keeping track of the sockets is much easier. In any case,	server applications don't normally have a single connection socket variable.	<P></DL><H2><A NAME="Heading17"></A>Workshop</H2><P>The Workshop provides quiz questions to help you solidify your understanding ofthe material covered and exercises to provide you with experience in using what you'velearned. The answers to the quiz questions and exercises are provided in AppendixB, &quot;Answers.&quot;</P><P><H3><A NAME="Heading18"></A>Quiz</H3><DL>	<DT></DT>	<DD><B>1. </B>What are the two things that a client application must know to be able	to connect to a server application?	<P>	<DT></DT>	<DD><B>2. </B>What CAsyncSocket function is used to enable a server application to	detect connection efforts by client applications?	<P>	<DT></DT>	<DD><B>3. </B>What CAsyncSocket member function is called to signal that data has	arrived through a socket connection?	<P>	<DT></DT>	<DD><B>4. </B>What function is called to signal that a connection has been established?	<P>	<DT></DT>	<DD><B>5. </B>What function do you use to send a message through a socket connection	to the application on the other end?	<P></DL><H3><A NAME="Heading19"></A>Exercise</H3><P>The server application that you wrote can handle only a single connection at atime. If a second application tries to open a connection to it while it's got anexisting connection to an application, the server application will crash. The servertries to accept the second connection into the socket that is already connected tothe first client application. Add a third socket object to the application that willbe used to reject additional client connections until the first client closes theconnection.</P><H1></H1><CENTER><P><HR><A HREF="../ch19/ch19.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch21/ch21.htm"><IMGSRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR><BR></P><P>&copy; <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. Allrights reserved.</CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -