📄 multi-threaded client-server socket class - the code project - internet & network.mht
字号:
<TR>
<TD width=3D"40%">systat</TD>
<TD width=3D"20%">11</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">netstat</TD>
<TD width=3D"20%">15</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">ftp-data</TD>
<TD width=3D"20%">20</TD>
<TD width=3D"40%">TCP File Transfer Protocol =
(data)</TD></TR>
<TR>
<TD width=3D"40%">ftp</TD>
<TD width=3D"20%">21</TD>
<TD width=3D"40%">TCP File Transfer Protocol</TD></TR>
<TR>
<TD width=3D"40%">smtp</TD>
<TD width=3D"20%">25</TD>
<TD width=3D"40%">TCP Simple Mail Transfer =
Protocol</TD></TR>
<TR>
<TD width=3D"40%">time</TD>
<TD width=3D"20%">37</TD>
<TD width=3D"40%">TCP Time Server</TD></TR>
<TR>
<TD width=3D"40%">time</TD>
<TD width=3D"20%">37</TD>
<TD width=3D"40%">UDP Time Server</TD></TR>
<TR>
<TD width=3D"40%">name</TD>
<TD width=3D"20%">42</TD>
<TD width=3D"40%">UDP Name Server</TD></TR>
<TR>
<TD width=3D"40%">whois</TD>
<TD width=3D"20%">43</TD>
<TD width=3D"40%">TCP nicname</TD></TR>
<TR>
<TD width=3D"40%">domain</TD>
<TD width=3D"20%">53</TD>
<TD width=3D"40%">UDP</TD></TR>
<TR>
<TD width=3D"40%">domain</TD>
<TD width=3D"20%">53</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">tftp</TD>
<TD width=3D"20%">69</TD>
<TD width=3D"40%">UDP</TD></TR>
<TR>
<TD width=3D"40%">rje</TD>
<TD width=3D"20%">77</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">finger</TD>
<TD width=3D"20%">79</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">link</TD>
<TD width=3D"20%">87</TD>
<TD width=3D"40%">TCP ttylink</TD></TR>
<TR>
<TD width=3D"40%">supdup</TD>
<TD width=3D"20%">95</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">hostname</TD>
<TD width=3D"20%">101</TD>
<TD width=3D"40%">TCP hostname</TD></TR>
<TR>
<TD width=3D"40%">pop-2</TD>
<TD width=3D"20%">109</TD>
<TD width=3D"40%">TCP Post Office Protocol</TD></TR>
<TR>
<TD width=3D"40%">uucp-path</TD>
<TD width=3D"20%">117</TD>
<TD width=3D"40%">TCP</TD></TR>
<TR>
<TD width=3D"40%">nntp</TD>
<TD width=3D"20%">119</TD>
<TD width=3D"40%">TCP Network News Transfer =
Protocol</TD></TR>
<TR>
<TD width=3D"40%">ntp</TD>
<TD width=3D"20%">123</TD>
<TD width=3D"40%">TCP Network Time =
Protocol</TD></TR></TBODY></TABLE>
<P>Ports in the region 1-255 are reserved by TCP/IP. The =
system may=20
reserve more. User processes may have their own ports above =
1023.=20
The function <CODE>getservbyname</CODE> can be used to find =
the port=20
for a service that is registered.</P>
<H3>Sockets</H3>
<P>A socket is a data structure maintained by the system to =
handle=20
network connections. A socket is created using the call=20
<CODE>socket</CODE>. It returns an integer that is like a =
file=20
descriptor. In fact, under Windows, this handle can be used =
with=20
<CODE>ReadFile</CODE> and <CODE>WriteFile</CODE> =
functions.</P><PRE><SPAN class=3Dcpp-preprocessor>#include =
<sys/types.h></SPAN>
<SPAN class=3Dcpp-preprocessor>#include <sys/socket.h></SPAN>
<SPAN class=3Dcpp-keyword>int</SPAN> socket(<SPAN =
class=3Dcpp-keyword>int</SPAN> family, <SPAN =
class=3Dcpp-keyword>int</SPAN> type, <SPAN =
class=3Dcpp-keyword>int</SPAN> protocol);</PRE>
<P>Here "family" will be <CODE>AF_INET</CODE> for IP =
communications,=20
<CODE>protocol</CODE> will be zero, and <CODE>type</CODE> =
will=20
depend on whether TCP or UDP is used. Two processes wishing =
to=20
communicate over a network create a socket each. These are =
similar=20
to two ends of a pipe - but the actual pipe does not yet =
exist.</P>
<H3>Connection oriented (TCP)</H3>
<P>One process (server) makes its socket known to the system =
using=20
<CODE>bind</CODE>. This will allow other sockets to find it. =
It then=20
"listens" on this socket to "accept" any incoming messages. =
The=20
other process (client) establishes a network connection to =
it, and=20
then the two exchange messages. As many messages as needed =
may be=20
sent along this channel, in either direction.</P>
<H4>Server:</H4>
<UL>
<LI>create endpoint (<CODE>socket()</CODE>)=20
<LI>bind address (<CODE>bind()</CODE>)=20
<LI>specify queue (<CODE>listen()</CODE>)=20
<LI>wait for connection (<CODE>accept()</CODE>)=20
<LI>transfer data =
(<CODE>read()</CODE>/<CODE>write()</CODE>)=20
</LI></UL>
<H4>Client:</H4>
<UL>
<LI>create endpoint (<CODE>socket()</CODE>)=20
<LI>connect to server (<CODE>connect()</CODE>)=20
<LI>transfer data =
(<CODE>read()</CODE>/<CODE>write()</CODE>)=20
</LI></UL>
<H3>Connectionless (UDP)</H3>
<P>In a connectionless protocol both sockets have to make =
their=20
existence known to the system using <CODE>bind</CODE>. This =
is=20
because each message is treated separately, so the client =
has to=20
find the server each time it sends a message and vice versa. =
When=20
<CODE>bind</CODE> is called, it binds to a new port - it =
cannot bind=20
to one already in use. If you specify the port as zero, the =
system=20
gives you a currently unused port. Because of this extra =
task on=20
each message send, the processes do not use=20
<CODE>read</CODE>/<CODE>write</CODE> but=20
<CODE>recvfrom</CODE>/<CODE>sendto</CODE>. These functions =
take as=20
parameters the socket to write to, and the address of the =
service on=20
the remote machine.</P>
<H4>Server:</H4>
<UL>
<LI>create endpoint (<CODE>socket()</CODE>)=20
<LI>bind address (<CODE>bind(</CODE>))=20
<LI>transfer data =
(<CODE>sendto()</CODE>/<CODE>recvfrom()</CODE>)=20
</LI></UL>
<H4>Client:</H4>
<UL>
<LI>create endpoint (<CODE>socket()</CODE>)=20
<LI>bind address (<CODE>bind()</CODE>) (optional if=20
<CODE>connect</CODE> is called)=20
<LI>connect to server (<CODE>connect()</CODE>)=20
<LI>transfer data =
(<CODE>sendto()</CODE>/<CODE>recvfrom()</CODE>)=20
</LI></UL>
<H2>Version History</H2><PRE><SPAN =
class=3Dcpp-comment>/////////////////////////////////////////////////////=
///////////////////</SPAN>
<SPAN class=3Dcpp-comment>// File: SocketComm.cpp</SPAN>
<SPAN class=3Dcpp-comment>// Version: 1.2</SPAN>
<SPAN class=3Dcpp-comment>//</SPAN>
<SPAN class=3Dcpp-comment>// 1.0 - Initial release.</SPAN>
<SPAN class=3Dcpp-comment>// 1.1 - Added support for Smart Addressing =
mode</SPAN>
<SPAN class=3Dcpp-comment>// 1.2 - Fixed various issues with address =
list (in UDP mode)</SPAN>
<SPAN =
class=3Dcpp-comment>/////////////////////////////////////////////////////=
///////////////////</SPAN></PRE>
<H2>How to Use</H2>
<P>This class can be used to create a TCP or UDP socket. Its =
use is=20
very simple. First of all, <CODE>CSocketComm</CODE> class is =
not=20
completed by itself for server operation, this class must be =
derived. Fortunately, only two functions need to be created, =
<CODE>OnDataReceived</CODE> and <CODE>OnEvent</CODE>. The =
default=20
functions don't do anything.</P>
<P>Now to create and start a server socket, do the =
following:</P><PRE><SPAN class=3Dcpp-comment>// To use TCP socket</SPAN>
<SPAN class=3Dcpp-comment>// no smart addressing - we use connection =
oriented</SPAN>
m_SocketObject.SetSmartAddressing( <SPAN =
class=3Dcpp-keyword>false</SPAN> );=20
m_SocketObject.CreateSocket( m_strPort, AF_INET, SOCK_STREAM,<SPAN =
class=3Dcpp-literal>0</SPAN>); <SPAN class=3Dcpp-comment>// TCP</SPAN>
<SPAN class=3Dcpp-comment>// To use UDP socket</SPAN>
m_SocketObject.SetSmartAddressing( <SPAN class=3Dcpp-keyword>true</SPAN> =
);
m_SocketObject.CreateSocket( m_strPort,=20
AF_INET, SOCK_DGRAM, SO_BROADCAST); <SPAN class=3Dcpp-comment>// =
UDP</SPAN>
<SPAN class=3Dcpp-comment>// Now you may start the server/client thread =
to do the work for you...</SPAN>
m_SocketObject.WatchComm();</PRE>
<P>To create and start a client socket, do the =
following:</P><PRE><SPAN class=3Dcpp-comment>// To use TCP socket</SPAN>
m_SocketObject.ConnectTo( strServer, m_strPort, AF_INET, SOCK_STREAM); =
<SPAN class=3Dcpp-comment>// TCP</SPAN>
<SPAN class=3Dcpp-comment>// To use UDP socket</SPAN>
m_SocketObject.ConnectTo( strServer, m_strPort, AF_INET, SOCK_DGRAM); =
<SPAN class=3Dcpp-comment>// UDP</SPAN>
<SPAN class=3Dcpp-comment>// Now you may start the server/client thread =
to do the work for you...</SPAN>
m_SocketObject.WatchComm();</PRE>
<H2>References</H2>
<UL>
<LI><A=20
=
href=3D"http://www.cisco.com/univercd/cc/td/doc/product/software/ioss390/=
ios390sk/sklibfun.htm"=20
target=3D_blank>Socket Library Functions</A>=20
<LI><A=20
=
href=3D"http://msdn.microsoft.com/msdnmag/issues/1000/Winsock/Winsock.asp=
"=20
target=3D_blank>Windows Sockets 2.0: Write Scalable =
Winsock Apps=20
Using Completion Ports</A> </LI></UL>
<H2>History</H2>
<UL>
<LI>31 Aug 2002 - Updated source code.=20
<LI>01 Mar 2004 - Updated source code.=20
<LI>02 Apr 2004 - Fixed bug when sending message to =
broadcast=20
address.</LI></UL><!-- Article Ends --></DIV></SPAN>
<SCRIPT =
src=3D"http://www.codeproject.com/script/togglePre.js"=20
type=3Dtext/javascript></SCRIPT>
<H2>About Ernest Laurentin</H2>
<DIV style=3D"OVERFLOW: hidden">
<TABLE border=3D0>
<TBODY>
<TR vAlign=3Dtop>
<TD class=3DsmallText noWrap><BR></TD>
<TD class=3DsmallText>Ernest is just a passionate =
cool-dude=20
about programming.<BR>MCSD+MCAD (C#, .NET)<BR>Area of=20
interest: User Interface, GDI/GDI+, KDE, XML. Embedded =
development with Windows CE .NET.<BR>Programming =
Skills:=20
C/C++, C++/CLI, C#, Java, VB (UI prototype), =
ASP.NET.<BR><BR>I=20
hope you will enjoy my contributions.
<P class=3DsmallText>Click <A=20
=
href=3D"http://www.codeproject.com/script/profile/whos_who.asp?vt=3Darts&=
amp;id=3D12809">here</A>=20
to view Ernest Laurentin's online=20
profile.</P></TD></TR></TBODY></TABLE></DIV><BR>
<TABLE cellPadding=3D4 width=3D"100%" border=3D0>
<TBODY>
<TR vAlign=3Dtop>
<TD width=3D"100%">
<H2>Other popular Internet & Network =
articles:</H2>
<UL>
<LI><A=20
=
href=3D"http://www.codeproject.com/internet/ndk.asp">Network=20
Development Kit 2.0</A>
<DIV class=3DsmallText>Network Development Kit is a =
set of=20
simple classes for a client-server =
architecture.</DIV>
<LI><A=20
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -