diff options
Diffstat (limited to 'docs/tutorials/008')
-rw-r--r-- | docs/tutorials/008/008-broadcast.dsp | 102 | ||||
-rw-r--r-- | docs/tutorials/008/008-direct.dsp | 102 | ||||
-rw-r--r-- | docs/tutorials/008/008-server.dsp | 102 | ||||
-rw-r--r-- | docs/tutorials/008/Makefile | 74 | ||||
-rw-r--r-- | docs/tutorials/008/broadcast_client.cpp | 80 | ||||
-rw-r--r-- | docs/tutorials/008/combine.shar | 465 | ||||
-rw-r--r-- | docs/tutorials/008/directed_client.cpp | 107 | ||||
-rw-r--r-- | docs/tutorials/008/page01.html | 73 | ||||
-rw-r--r-- | docs/tutorials/008/page02.html | 160 | ||||
-rw-r--r-- | docs/tutorials/008/page03.html | 145 | ||||
-rw-r--r-- | docs/tutorials/008/page04.html | 133 | ||||
-rw-r--r-- | docs/tutorials/008/page05.html | 39 | ||||
-rw-r--r-- | docs/tutorials/008/server.cpp | 115 |
13 files changed, 0 insertions, 1697 deletions
diff --git a/docs/tutorials/008/008-broadcast.dsp b/docs/tutorials/008/008-broadcast.dsp deleted file mode 100644 index b7aafc7ba00..00000000000 --- a/docs/tutorials/008/008-broadcast.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="008 broadcast" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=008 broadcast - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "008-broadcast.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "008-broadcast.mak" CFG="008 broadcast - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "008 broadcast - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "008 broadcast - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "008 broadcast - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "008 broadcast - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../broadcast_client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "008 broadcast - Win32 Release"
-# Name "008 broadcast - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=broadcast_client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/008/008-direct.dsp b/docs/tutorials/008/008-direct.dsp deleted file mode 100644 index a8f6d2386ce..00000000000 --- a/docs/tutorials/008/008-direct.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="008 direct" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=008 direct - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "008-direct.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "008-direct.mak" CFG="008 direct - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "008 direct - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "008 direct - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "008 direct - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "008 direct - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../directed_client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "008 direct - Win32 Release"
-# Name "008 direct - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=directed_client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/008/008-server.dsp b/docs/tutorials/008/008-server.dsp deleted file mode 100644 index 8db64b2fa66..00000000000 --- a/docs/tutorials/008/008-server.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="008 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=008 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "008-server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "008-server.mak" CFG="008 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "008 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "008 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "008 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "008 server - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "008 server - Win32 Release"
-# Name "008 server - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/008/Makefile b/docs/tutorials/008/Makefile deleted file mode 100644 index b595ecbc814..00000000000 --- a/docs/tutorials/008/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server directed_client broadcast_client - -FILES = - -BUILD = $(VBIN) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -bli0 -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre ; chmod +r *.html - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && $(RM) hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/008/broadcast_client.cpp b/docs/tutorials/008/broadcast_client.cpp deleted file mode 100644 index 126b125ffc4..00000000000 --- a/docs/tutorials/008/broadcast_client.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// $Id$ - -#include "ace/SOCK_Dgram_Bcast.h" -#include "ace/INET_Addr.h" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int -main (int argc,char *argv[]) -{ - ACE_INET_Addr local ((u_short) 0); - - /* Instead of creating the ACE_SOCK_Dgram we created last time, - we'll create an ACE_SOCK_Dgram_Bcast. "Bcast" means, of course, - "Broadcast". This ACE object is clever enough to go out to the OS - and find all of the network interfaces. When you send() on a - Dgram_Bcast, it will send the datagram out on all of those - interfaces. This is quiet handy if you do it on a multi-homed - host that plays router... */ - ACE_SOCK_Dgram_Bcast dgram; - - if (dgram.open (local) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "datagram open"), - -1); - - char buf[BUFSIZ]; - - sprintf (buf, "Hello World!"); - - /* The only other difference between us and the directed client is - that we don't specify a host to receive the datagram. Instead, we - use the magic value "INADDR_BROADCAST". All hosts are obliged to - respond to datagrams directed to this address the same as they - would to datagrams sent to their hostname. - - Remember, the Dgram_Bcast will send a datagram to all interfaces - on the host. That's true even if the address is for a specific - host (and the host address makes sense for the interface). The - real power is in using an INADDR_BROADCAST addressed datagram - against all interfaces. */ - - ACE_INET_Addr remote (PORT, - INADDR_BROADCAST); - - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Sending (%s) to the server.\n", - buf)); - - if (dgram.send (buf, - ACE_OS::strlen (buf) + 1, - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "send"), - -1); - - if (dgram.recv (buf, - sizeof (buf), - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "recv"), - -1); - - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) The server said: %s\n", - buf)); - - /* Using the "remote" object instance, find out where the server - lives. We could then save this address and use directed datagrams - to chat with the server for a while. */ - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) The server can be found at: (%s:%d)\n", - remote.get_host_name(), - PORT)); - - return 0; -} diff --git a/docs/tutorials/008/combine.shar b/docs/tutorials/008/combine.shar deleted file mode 100644 index f12ae4c4ee3..00000000000 --- a/docs/tutorials/008/combine.shar +++ /dev/null @@ -1,465 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1999-01-26 19:48 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/008'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 515 -rw-rw-r-- hdr -# 59 -rw-rw-r-- bodies -# 2769 -rw-rw-r-- page01.pre -# 416 -rw-rw-r-- page02.pre -# 345 -rw-rw-r-- page03.pre -# 481 -rw-rw-r-- page04.pre -# 578 -rw-rw-r-- page05.pre -# 952 -rw-rw-r-- page02.pst -# 367 -rw-rw-r-- page03.pst -# 1173 -rw-rw-r-- page04.pst -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh30434; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> -X -X -<P> -<HR WIDTH="100%"> -X -SHAR_EOF - $shar_touch -am 0121153899 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -e74ecd3335da844c263f961a8ba5f867 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 515 -eq "$shar_count" || - $echo 'hdr:' 'original size' '515,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -server.cpp -directed_client.cpp -broadcast_client.cpp -SHAR_EOF - $shar_touch -am 0121153799 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -707d1735ca25694e2b5fddc1f6e7e124 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 59 -eq "$shar_count" || - $echo 'bodies:' 'original size' '59,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -<P>In a lot of IPC programming, the clients know where the servers -are. A mail client, for instance, has a configuration file that says -where the mail host is. Your web browser has a "location" field that -you type into to give it a destination. -X -<P>What if you have written a server application and then you execute it -on several systems in your network? All of the instances are probably -more or less equal to the client's point of view, so you don't want to -"configure" the clients to a single server each. Likewise, you -want the ability to add and remove servers at any time so you can't just -give the clients a list to choose from. -X -<P>So... how do the clients know where the servers are? -X -<P>Let 'em ask! -X -<P>Datagrams are great for this. You can toss a datagram out onto -the network and any servers listening at the correct port will* hear it. -Like ACE_SOCK_Stream that we've seen before, you can get the peer address -from a datagram. With that, the server can send a response -back to the client. The client, in turn, can pull the peer address -out and know exactly where the server lives. -X -<P>In this tutorial we'll develop three applications: a server listening -for datagrams, a client that can send to a known host and a client that -can send to the entire (sub)network. In the next tutorial, we'll -expand on this to make the server a bit more prudish. -<P> -Kirthika's abstract: -<UL> -Here, we play with datagram sockets and use it for server discovery by -the client. Datagrams are used by UDP, which is an unreliable and -connectionless protocol. Datagrams packets are generally very small in -size and aren't designed to be used to handle serious communication -between the server and the client. -<P> -The server waits for datagrams to arrive at a fixed port. -The client either sends to a datagram to the server at a known host, -which is not really the case generally, as the client needs to discover -the server and so it needs to broadcast its datagram request in its -subnet. Then, all servers listening at that interface receive it. The -appropriate server will then handle the request. Remember that -no solid connection is made. On the recv() itself the server obtains the -address of the remote client and then communicates with it. -<P> -Thus, we get a fair glimpse of using another means of communication via -datagrams. -</UL> -<P><FONT SIZE=-1>* Actually, the servers <I>might</I> hear the datagram. -Datagrams are rather unreliable. (Sort of like some operating systems -I know.) Still, if the network traffic isn't too bad, they generally -get through. Your clients can always send out more queries if there -aren't any responses in a timely fashion.</FONT> -X -SHAR_EOF - $shar_touch -am 0121155099 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -829e35e4a7b8e8c75e38abf492033395 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 2769 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '2769,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -X -<P>The first thing we want to look at is <A HREF="server.cpp">server.cpp</A>. -This is a pretty simple application that listens for datagrams at a known -port and sends back a response. In order to implement a true "discovery" -mechanism, the server will have to be a little bit more picky about who -it responds to. We'll tackle that issue in the next tutorial though... -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 0121153899 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -6b27ef52d53a13d2d9e5a5ad16e9be4d page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 416 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '416,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -X -<P>In <A HREF="directed_client.cpp">directed_client.cpp</A> we create a -client that knows how to send a datagram to a server on a known host. -This is a good thing if you know where the server lives and want to have -a conversation. The Unix <I>talk</I> utilitiy, for instance, -could be written this way. -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 0121153899 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -aa0724ca0a09f5b5e6c7e3f355646111 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 345 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '345,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -In <A HREF="broadcast_client.cpp">broadcast_client.cpp</A> we -find out how to send a single datagram to every host on our (sub)network. -I have to say <I>(sub)network</I> because broadcast datagrams typically -are not passed through routers. So, if your network admin has divided -up your network into subnets, your broadcasts will likey stay on the -subnet you're a part of. -X -<P>I've only commented the parts that are different from the directed_client. -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 0124144899 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -8811bded669a7a7be85a4878d5076190 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 481 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '481,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -<BR>That's it for this tutorial. In the next one we'll add some intelligence -to the data put into the datagrams. By doing so, we'll be able to -classify our clients and servers into groups. By combining the data -content and the server's port we can get fairly fine-grained control over -who talks to who. -X -<P>For you convenience: -<UL> -<LI> -<A HREF="server.cpp">server.cpp</A></LI> -X -<LI> -<A HREF="directed_client.cpp">directed_client.cpp</A></LI> -X -<LI> -<A HREF="broadcast_client.cpp">broadcast_client.cpp</A></LI> -X -<LI> -<A HREF="Makefile">Makefile</A></LI> -</UL> -SHAR_EOF - $shar_touch -am 0121153799 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -b05fdac8c7eb81813c74eb99525cf601 page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 578 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '578,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pst ============== -if test -f 'page02.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pst' '(file already exists)' -else - $echo 'x -' extracting 'page02.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pst' && -<HR WIDTH="100%"> -X -<P>And that's really all there is to it. Obviously there is some -room for improvement. The most blatant is the somewhat small buffer -size for receiving the datagram. I've never been able to get a solid -answer on datagram sizes. The theoretical limit is just under 64k -but you have to deal with fragmentation. Some readings indicate that -8k is a reasonable size, others go much smaller. My general rule -of thumb is to keep datagrams relatively small (eg -- under 8k or so) and -test a lot. If you find that your routers are fragmenting your larger -datagrams, back off to something smaller. Of course, if you must -send 100k and can only do so 1k at a time, you'll have to worry about retransmissions -& reordering. At that point, you might consider going to TCP. -Remember: datagrams are unreliable! Don't try to make 'em do -something they werent' designed for! -SHAR_EOF - $shar_touch -am 0121153899 'page02.pst' && - chmod 0664 'page02.pst' || - $echo 'restore of' 'page02.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pst:' 'MD5 check failed' -3cb7da5f75a40616f6cc498a731f4a16 page02.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`" - test 952 -eq "$shar_count" || - $echo 'page02.pst:' 'original size' '952,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pst ============== -if test -f 'page03.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pst' '(file already exists)' -else - $echo 'x -' extracting 'page03.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pst' && -<HR WIDTH="100%"> -X -<P>That's all neat and good but the point of what we're doing here is not -to talk to a server we know about but to discover servers we don't know -about. Now, you could send a directed datagram to every possible -host address on your network but that's not a very nice thing to do. -On the next page, we'll find out the right approach... -X -SHAR_EOF - $shar_touch -am 0121153899 'page03.pst' && - chmod 0664 'page03.pst' || - $echo 'restore of' 'page03.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pst:' 'MD5 check failed' -0fcbc10be47175a0d42590fb4adab43b page03.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pst'`" - test 367 -eq "$shar_count" || - $echo 'page03.pst:' 'original size' '367,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pst ============== -if test -f 'page04.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pst' '(file already exists)' -else - $echo 'x -' extracting 'page04.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pst' && -<HR WIDTH="100%"> -X -<P> About that subnet thing: -<BLOCKQUOTE>If you run this client on a host that has multiple network -interfaces, the broadcast will go to all of those (sub)networks. -What do you do, though, if you need to get past a router? My advice -is to write a server that will run on hosts on both sides of your router. -When a server on one side of the router receives a broadcast, it would -send a directed datagram to it's counterpart on the other side of the router. -The counterpart would then re-broadcast the original datagram on that sub-net. -Cheap, simple and effective.</BLOCKQUOTE> -One final word of warning: -<BLOCKQUOTE>When creating your broadcast datagrams you may see something -like this: <I>ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not -enable for this interface.: Unknown error</I>. There are some interfaces -(ppp, slip) that don't support broadcast datagrams. That's what you're -seeing here.</BLOCKQUOTE> -Ok, one more warning: -<blockquote>If you happen to have multiple servers running on your -network when you invoke this client, the response could come from any -one of them. -</blockquote> -X -SHAR_EOF - $shar_touch -am 0126194899 'page04.pst' && - chmod 0664 'page04.pst' || - $echo 'restore of' 'page04.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pst:' 'MD5 check failed' -2e01fc6b6638dfa77ed629c0e3e77e21 page04.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`" - test 1173 -eq "$shar_count" || - $echo 'page04.pst:' 'original size' '1173,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh30434 -exit 0 diff --git a/docs/tutorials/008/directed_client.cpp b/docs/tutorials/008/directed_client.cpp deleted file mode 100644 index d11367aa43e..00000000000 --- a/docs/tutorials/008/directed_client.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// $Id$ - -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -/* Once again, we use the default server port. In a "real" system, - the server's port (or ports) would be published in some way so that - clients would know where to "look". We could even add entries to - the operating system's services file and use a service name instead - of a number. We'll come back to that in some other tutorial - though. For now, let's stay simple. */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* Our goal here is to develop a client that can send a datagram to a - server running on a known host. We'll use a command-line argument - to specify the hostname instead of hard-coding it. */ -int -main (int argc,char *argv[]) -{ - /* All datagrams must have a point of origin. Since we intend to - transmit instead of receive, we initialize an address with zero - and let the OS choose a port for us. We could have chosen our own - value between 1025 and 65535 as long as it isn't already in use. - - The biggest difference between client and server when datagrams - are used is the fact that servers tend to have a known/fixed - address at which they listen and clients tend to have arbitrary - addresses assigned by the OS. */ - ACE_INET_Addr local((u_short) 0); - - /* And here is our datagram object. */ - ACE_SOCK_Dgram dgram; - - /* Notice that this looks a lot like the server application. - There's no difference in creating server datagrams an client - datagrams. You can even use a zero-constructed address for your - server datagram as long as you tell the client where you're - listening (eg -- by writting into a file or some such). */ - if (dgram.open (local) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "datagram open"), - -1); - - /* Yep. We've seen this before too... */ - char buf[BUFSIZ]; - - /* Ok, now we're doing something different. */ - sprintf (buf, "Hello World!"); - - /* Just like sending a telegram, we have to address our datagram. - Here, we create an address object at the desired port on the - chosen host. To keep us from crashing, we'll provide a default - host name if we aren't given one. */ - ACE_INET_Addr remote (PORT, - argc > 1 ? argv[1] : "localhost"); - - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Sending (%s) to the server.\n", - buf)); - /* Now we send our buffer of stuff to the remote address. This is - just exactly what the server did after receiving a client message. - Datagrams are rather orthogonal that way: they don't generally - make much of a fuss about being either client or server. */ - if (dgram.send (buf, - ACE_OS::strlen (buf) + 1, - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "send"), - -1); - - /* Now we've turned around and put ourselves into "server mode" by - invoking the recv() method. We know our server is going to send - us something, so we hang out here and wait for it. Because we - know datagrams are unreliable, there is a chance that the server - will respond but we won't hear. You might consider providing a - timeout on the recv() in that case. If recv() fails due to - timeout it will return -1 and you can then resend your query and - attempt the recv() again. - - Like the server application, we have to give the recv() an - uninitialized addr object so that we can find out who is talking - back to us. */ - if (dgram.recv (buf, - sizeof (buf), - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "recv"), - -1); - - /* Find out what the server had to say. */ - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) The server said: %s\n", - buf)); - - /* Using the "remote" object instance, find out where the server - lives. We could then save this address and use directed datagrams - to chat with the server for a while. */ - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) The server can be found at: (%s:%d)\n", - remote.get_host_name(), - PORT)); - - return 0; -} diff --git a/docs/tutorials/008/page01.html b/docs/tutorials/008/page01.html deleted file mode 100644 index ce6f508f67a..00000000000 --- a/docs/tutorials/008/page01.html +++ /dev/null @@ -1,73 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In a lot of IPC programming, the clients know where the servers -are. A mail client, for instance, has a configuration file that says -where the mail host is. Your web browser has a "location" field that -you type into to give it a destination. - -<P>What if you have written a server application and then you execute it -on several systems in your network? All of the instances are probably -more or less equal to the client's point of view, so you don't want to -"configure" the clients to a single server each. Likewise, you -want the ability to add and remove servers at any time so you can't just -give the clients a list to choose from. - -<P>So... how do the clients know where the servers are? - -<P>Let 'em ask! - -<P>Datagrams are great for this. You can toss a datagram out onto -the network and any servers listening at the correct port will* hear it. -Like ACE_SOCK_Stream that we've seen before, you can get the peer address -from a datagram. With that, the server can send a response -back to the client. The client, in turn, can pull the peer address -out and know exactly where the server lives. - -<P>In this tutorial we'll develop three applications: a server listening -for datagrams, a client that can send to a known host and a client that -can send to the entire (sub)network. In the next tutorial, we'll -expand on this to make the server a bit more prudish. -<P> -Kirthika's abstract: -<UL> -Here, we play with datagram sockets and use it for server discovery by -the client. Datagrams are used by UDP, which is an unreliable and -connectionless protocol. Datagrams packets are generally very small in -size and aren't designed to be used to handle serious communication -between the server and the client. -<P> -The server waits for datagrams to arrive at a fixed port. -The client either sends to a datagram to the server at a known host, -which is not really the case generally, as the client needs to discover -the server and so it needs to broadcast its datagram request in its -subnet. Then, all servers listening at that interface receive it. The -appropriate server will then handle the request. Remember that -no solid connection is made. On the recv() itself the server obtains the -address of the remote client and then communicates with it. -<P> -Thus, we get a fair glimpse of using another means of communication via -datagrams. -</UL> -<P><FONT SIZE=-1>* Actually, the servers <I>might</I> hear the datagram. -Datagrams are rather unreliable. (Sort of like some operating systems -I know.) Still, if the network traffic isn't too bad, they generally -get through. Your clients can always send out more queries if there -aren't any responses in a timely fashion.</FONT> - -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/008/page02.html b/docs/tutorials/008/page02.html deleted file mode 100644 index c501c12bad9..00000000000 --- a/docs/tutorials/008/page02.html +++ /dev/null @@ -1,160 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - - -<P>The first thing we want to look at is <A HREF="server.cpp">server.cpp</A>. -This is a pretty simple application that listens for datagrams at a known -port and sends back a response. In order to implement a true "discovery" -mechanism, the server will have to be a little bit more picky about who -it responds to. We'll tackle that issue in the next tutorial though... - -<P> -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=red>/* Our datagram server will, of course, need to create a datagram. - We'll also need an address object so that we know where to listen. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Dgram.h">ace/SOCK_Dgram.h</A>" -<font color=blue>#include</font> "<A HREF="../../../ace/INET_Addr.h">ace/INET_Addr.h</A>" - -<font color=red>/* Use the typical TCP/IP port address for receiving datagrams. */</font> -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int -main (int, char**) -{ - <font color=red>/* This is where we'll listen for datagrams coming from the clients. - We'll give this address to the open() method below to enable the - listener. */</font> - ACE_INET_Addr local (PORT); - - <font color=red>/* A simply constructed datagram that we'll listen with. */</font> - ACE_SOCK_Dgram dgram; - - <font color=red>/* Like most ACE objects, the datagram has to be opened before it - can be uses. Of course, -1 on failure. - - A datagram will fail to open if there is already a datagram - listening at the port we've chosen. It *is* OK to open a datagram - at a port where there is an ACE_SOCK_Stream though. This is - because datagrams are UDP and SOCK_Stream is TCP and the two don't - cross paths. */</font> - if (dgram.open (local) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>open</font>"), - -1); - - <font color=red>/* Create a simple buffer to receive the data. You generally need - to provide a buffer big enough for the largest datagram you expect - to receive. Some platforms will let you read a little and then - some more later but other platforms will throw out whatever part - of the datagram you don't get with the first read. (This is on a - per-datagram basis BTW.) The theoretical limit on a datagram is - about 64k. The realistic limit (because of routers & such) is - much smaller. Choose your buffer size based on your application's - needs. */</font> - char buf[BUFSIZ]; - - <font color=red>/* Unlike ACE_SOCK_Stream, datagrams are unconnected. That is, - there is no "<font color=green>virtual circuit</font>" between server and client. Because - of this, the server has to provide a placeholder for the OS to - fill in the source (client) address information on the recv. You - can initialize this INET_Addr to anything, it will be overwritten - when the data arrives. */</font> - ACE_INET_Addr remote; - - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) starting up server daemon\n</font>")); - - <font color=red>/* Receive datagrams as long as we're able. */</font> - while (dgram.recv (buf, - sizeof (buf), - remote) != -1) - { - <font color=red>/* Display a brief message about our progress. Notice how we - use the 'remote' object to display the address of the client. - With an ACE_SOCK_Stream we used get_remote_addr() to get the - address the socket is connected to. Because datagrams are - unconnected, we use the addr object provided to recv(). */</font> - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) Data (%s) from client (%s)\n</font>", - buf, - remote.get_host_name ())); - - <font color=red>/* To respond to the client's query, we have to become a client - ourselves. To do so, we need an anonymous local address from - which we'll send the response and a datagram in which to send - it. (An anonymous address is simply one where we let the OS - choose a port for us. We really don't care what it is. */</font> - ACE_INET_Addr local ((u_short) 0); - ACE_SOCK_Dgram client; - - <font color=red>/* Open up our response datagram as always. */</font> - if (client.open (local) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>client open</font>"), - -1); - return 0; - } - - <font color=red>/* Build a witty response... */</font> - sprintf (buf, - "<font color=green>I am here</font>"); - - <font color=red>/* and send it to the client. Notice the symmetry with the - recv() method. Again, the unconnected nature of datagrams - forces us to specify an address object with each read/write - operation. In the case of read (recv()) that's where the OS - stuffs the address of the datagram sender. In the case of - write (send()) that we're doing here, the address is where we - want the network to deliver the data. - - Of course, we're assuming that the client will be listening - for our reply... */</font> - if (client.send (buf, - <font color=#008888>ACE_OS::strlen</font> (buf) + 1, - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>send</font>"), - -1); - } - - return 0; -} -</PRE> -<HR WIDTH="100%"> - -<P>And that's really all there is to it. Obviously there is some -room for improvement. The most blatant is the somewhat small buffer -size for receiving the datagram. I've never been able to get a solid -answer on datagram sizes. The theoretical limit is just under 64k -but you have to deal with fragmentation. Some readings indicate that -8k is a reasonable size, others go much smaller. My general rule -of thumb is to keep datagrams relatively small (eg -- under 8k or so) and -test a lot. If you find that your routers are fragmenting your larger -datagrams, back off to something smaller. Of course, if you must -send 100k and can only do so 1k at a time, you'll have to worry about retransmissions -& reordering. At that point, you might consider going to TCP. -Remember: datagrams are unreliable! Don't try to make 'em do -something they werent' designed for! -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/008/page03.html b/docs/tutorials/008/page03.html deleted file mode 100644 index 36c58e4d3c5..00000000000 --- a/docs/tutorials/008/page03.html +++ /dev/null @@ -1,145 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - - -<P>In <A HREF="directed_client.cpp">directed_client.cpp</A> we create a -client that knows how to send a datagram to a server on a known host. -This is a good thing if you know where the server lives and want to have -a conversation. The Unix <I>talk</I> utilitiy, for instance, -could be written this way. - -<P> -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Dgram.h">ace/SOCK_Dgram.h</A>" -<font color=blue>#include</font> "<A HREF="../../../ace/INET_Addr.h">ace/INET_Addr.h</A>" - -<font color=red>/* Once again, we use the default server port. In a "<font color=green>real</font>" system, - the server's port (or ports) would be published in some way so that - clients would know where to "<font color=green>look</font>". We could even add entries to - the operating system's services file and use a service name instead - of a number. We'll come back to that in some other tutorial - though. For now, let's stay simple. */</font> -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -<font color=red>/* Our goal here is to develop a client that can send a datagram to a - server running on a known host. We'll use a command-line argument - to specify the hostname instead of hard-coding it. */</font> -int -main (int argc,char *argv[]) -{ - <font color=red>/* All datagrams must have a point of origin. Since we intend to - transmit instead of receive, we initialize an address with zero - and let the OS choose a port for us. We could have chosen our own - value between 1025 and 65535 as long as it isn't already in use. - - The biggest difference between client and server when datagrams - are used is the fact that servers tend to have a known/fixed - address at which they listen and clients tend to have arbitrary - addresses assigned by the OS. */</font> - ACE_INET_Addr local((u_short) 0); - - <font color=red>/* And here is our datagram object. */</font> - ACE_SOCK_Dgram dgram; - - <font color=red>/* Notice that this looks a lot like the server application. - There's no difference in creating server datagrams an client - datagrams. You can even use a zero-constructed address for your - server datagram as long as you tell the client where you're - listening (eg -- by writting into a file or some such). */</font> - if (dgram.open (local) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>datagram open</font>"), - -1); - - <font color=red>/* Yep. We've seen this before too... */</font> - char buf[BUFSIZ]; - - <font color=red>/* Ok, now we're doing something different. */</font> - sprintf (buf, "<font color=green>Hello World!</font>"); - - <font color=red>/* Just like sending a telegram, we have to address our datagram. - Here, we create an address object at the desired port on the - chosen host. To keep us from crashing, we'll provide a default - host name if we aren't given one. */</font> - ACE_INET_Addr remote (PORT, - argc > 1 ? argv[1] : "<font color=green>localhost</font>"); - - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) Sending (%s) to the server.\n</font>", - buf)); - <font color=red>/* Now we send our buffer of stuff to the remote address. This is - just exactly what the server did after receiving a client message. - Datagrams are rather orthogonal that way: they don't generally - make much of a fuss about being either client or server. */</font> - if (dgram.send (buf, - <font color=#008888>ACE_OS::strlen</font> (buf) + 1, - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>send</font>"), - -1); - - <font color=red>/* Now we've turned around and put ourselves into "<font color=green>server mode</font>" by - invoking the recv() method. We know our server is going to send - us something, so we hang out here and wait for it. Because we - know datagrams are unreliable, there is a chance that the server - will respond but we won't hear. You might consider providing a - timeout on the recv() in that case. If recv() fails due to - timeout it will return -1 and you can then resend your query and - attempt the recv() again. - - Like the server application, we have to give the recv() an - uninitialized addr object so that we can find out who is talking - back to us. */</font> - if (dgram.recv (buf, - sizeof (buf), - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>recv</font>"), - -1); - - <font color=red>/* Find out what the server had to say. */</font> - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) The server said: %s\n</font>", - buf)); - - <font color=red>/* Using the "<font color=green>remote</font>" object instance, find out where the server - lives. We could then save this address and use directed datagrams - to chat with the server for a while. */</font> - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) The server can be found at: (%s:%d)\n</font>", - remote.get_host_name(), - PORT)); - - return 0; -} -</PRE> -<HR WIDTH="100%"> - -<P>That's all neat and good but the point of what we're doing here is not -to talk to a server we know about but to discover servers we don't know -about. Now, you could send a directed datagram to every possible -host address on your network but that's not a very nice thing to do. -On the next page, we'll find out the right approach... - -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/008/page04.html b/docs/tutorials/008/page04.html deleted file mode 100644 index faaaed77dce..00000000000 --- a/docs/tutorials/008/page04.html +++ /dev/null @@ -1,133 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -In <A HREF="broadcast_client.cpp">broadcast_client.cpp</A> we -find out how to send a single datagram to every host on our (sub)network. -I have to say <I>(sub)network</I> because broadcast datagrams typically -are not passed through routers. So, if your network admin has divided -up your network into subnets, your broadcasts will likey stay on the -subnet you're a part of. - -<P>I've only commented the parts that are different from the directed_client. -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Dgram_Bcast.h">ace/SOCK_Dgram_Bcast.h</A>" -<font color=blue>#include</font> "<A HREF="../../../ace/INET_Addr.h">ace/INET_Addr.h</A>" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int -main (int argc,char *argv[]) -{ - ACE_INET_Addr local ((u_short) 0); - - <font color=red>/* Instead of creating the ACE_SOCK_Dgram we created last time, - we'll create an ACE_SOCK_Dgram_Bcast. "<font color=green>Bcast</font>" means, of course, - "<font color=green>Broadcast</font>". This ACE object is clever enough to go out to the OS - and find all of the network interfaces. When you send() on a - Dgram_Bcast, it will send the datagram out on all of those - interfaces. This is quiet handy if you do it on a multi-homed - host that plays router... */</font> - ACE_SOCK_Dgram_Bcast dgram; - - if (dgram.open (local) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>datagram open</font>"), - -1); - - char buf[BUFSIZ]; - - sprintf (buf, "<font color=green>Hello World!</font>"); - - <font color=red>/* The only other difference between us and the directed client is - that we don't specify a host to receive the datagram. Instead, we - use the magic value "<font color=green>INADDR_BROADCAST</font>". All hosts are obliged to - respond to datagrams directed to this address the same as they - would to datagrams sent to their hostname. - - Remember, the Dgram_Bcast will send a datagram to all interfaces - on the host. That's true even if the address is for a specific - host (and the host address makes sense for the interface). The - real power is in using an INADDR_BROADCAST addressed datagram - against all interfaces. */</font> - - ACE_INET_Addr remote (PORT, - INADDR_BROADCAST); - - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) Sending (%s) to the server.\n</font>", - buf)); - - if (dgram.send (buf, - <font color=#008888>ACE_OS::strlen</font> (buf) + 1, - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>send</font>"), - -1); - - if (dgram.recv (buf, - sizeof (buf), - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>recv</font>"), - -1); - - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) The server said: %s\n</font>", - buf)); - - <font color=red>/* Using the "<font color=green>remote</font>" object instance, find out where the server - lives. We could then save this address and use directed datagrams - to chat with the server for a while. */</font> - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) The server can be found at: (%s:%d)\n</font>", - remote.get_host_name(), - PORT)); - - return 0; -} -</PRE> -<HR WIDTH="100%"> - -<P> About that subnet thing: -<BLOCKQUOTE>If you run this client on a host that has multiple network -interfaces, the broadcast will go to all of those (sub)networks. -What do you do, though, if you need to get past a router? My advice -is to write a server that will run on hosts on both sides of your router. -When a server on one side of the router receives a broadcast, it would -send a directed datagram to it's counterpart on the other side of the router. -The counterpart would then re-broadcast the original datagram on that sub-net. -Cheap, simple and effective.</BLOCKQUOTE> -One final word of warning: -<BLOCKQUOTE>When creating your broadcast datagrams you may see something -like this: <I>ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not -enable for this interface.: Unknown error</I>. There are some interfaces -(ppp, slip) that don't support broadcast datagrams. That's what you're -seeing here.</BLOCKQUOTE> -Ok, one more warning: -<blockquote>If you happen to have multiple servers running on your -network when you invoke this client, the response could come from any -one of them. -</blockquote> - -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/008/page05.html b/docs/tutorials/008/page05.html deleted file mode 100644 index bb1b157098e..00000000000 --- a/docs/tutorials/008/page05.html +++ /dev/null @@ -1,39 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<BR>That's it for this tutorial. In the next one we'll add some intelligence -to the data put into the datagrams. By doing so, we'll be able to -classify our clients and servers into groups. By combining the data -content and the server's port we can get fairly fine-grained control over -who talks to who. - -<P>For you convenience: -<UL> -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="directed_client.cpp">directed_client.cpp</A></LI> - -<LI> -<A HREF="broadcast_client.cpp">broadcast_client.cpp</A></LI> - -<LI> -<A HREF="Makefile">Makefile</A></LI> -</UL> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/008/server.cpp b/docs/tutorials/008/server.cpp deleted file mode 100644 index 629c2dd42c8..00000000000 --- a/docs/tutorials/008/server.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// $Id$ - -/* Our datagram server will, of course, need to create a datagram. - We'll also need an address object so that we know where to listen. */ -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -/* Use the typical TCP/IP port address for receiving datagrams. */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int -main (int, char**) -{ - /* This is where we'll listen for datagrams coming from the clients. - We'll give this address to the open() method below to enable the - listener. */ - ACE_INET_Addr local (PORT); - - /* A simply constructed datagram that we'll listen with. */ - ACE_SOCK_Dgram dgram; - - /* Like most ACE objects, the datagram has to be opened before it - can be uses. Of course, -1 on failure. - - A datagram will fail to open if there is already a datagram - listening at the port we've chosen. It *is* OK to open a datagram - at a port where there is an ACE_SOCK_Stream though. This is - because datagrams are UDP and SOCK_Stream is TCP and the two don't - cross paths. */ - if (dgram.open (local) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "open"), - -1); - - /* Create a simple buffer to receive the data. You generally need - to provide a buffer big enough for the largest datagram you expect - to receive. Some platforms will let you read a little and then - some more later but other platforms will throw out whatever part - of the datagram you don't get with the first read. (This is on a - per-datagram basis BTW.) The theoretical limit on a datagram is - about 64k. The realistic limit (because of routers & such) is - much smaller. Choose your buffer size based on your application's - needs. */ - char buf[BUFSIZ]; - - /* Unlike ACE_SOCK_Stream, datagrams are unconnected. That is, - there is no "virtual circuit" between server and client. Because - of this, the server has to provide a placeholder for the OS to - fill in the source (client) address information on the recv. You - can initialize this INET_Addr to anything, it will be overwritten - when the data arrives. */ - ACE_INET_Addr remote; - - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) starting up server daemon\n")); - - /* Receive datagrams as long as we're able. */ - while (dgram.recv (buf, - sizeof (buf), - remote) != -1) - { - /* Display a brief message about our progress. Notice how we - use the 'remote' object to display the address of the client. - With an ACE_SOCK_Stream we used get_remote_addr() to get the - address the socket is connected to. Because datagrams are - unconnected, we use the addr object provided to recv(). */ - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Data (%s) from client (%s)\n", - buf, - remote.get_host_name ())); - - /* To respond to the client's query, we have to become a client - ourselves. To do so, we need an anonymous local address from - which we'll send the response and a datagram in which to send - it. (An anonymous address is simply one where we let the OS - choose a port for us. We really don't care what it is. */ - ACE_INET_Addr local ((u_short) 0); - ACE_SOCK_Dgram client; - - /* Open up our response datagram as always. */ - if (client.open (local) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "client open"), - -1); - return 0; - } - - /* Build a witty response... */ - sprintf (buf, - "I am here"); - - /* and send it to the client. Notice the symmetry with the - recv() method. Again, the unconnected nature of datagrams - forces us to specify an address object with each read/write - operation. In the case of read (recv()) that's where the OS - stuffs the address of the datagram sender. In the case of - write (send()) that we're doing here, the address is where we - want the network to deliver the data. - - Of course, we're assuming that the client will be listening - for our reply... */ - if (client.send (buf, - ACE_OS::strlen (buf) + 1, - remote) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "send"), - -1); - } - - return 0; -} |