Sie sind auf Seite 1von 32

Beej's Guide to Network Programming

Using Internet Sockets


Platform and Compiler
Most of the code contained within this document was compiled on a Linux PC using
Gnu's gcc compiler. It was also found to compile on HPUX using gcc. ote that e!er"
code snippet was not indi!iduall" tested.
Contents#
$hat is a soc%et&
'wo '"pes of Internet (oc%ets
Low le!el onsense and etwor% 'heor"
structs))*now these+ or aliens will destro" the planet,
Con!ert the ati!es,
IP -ddresses and How to .eal $ith 'hem
soc%et/0))Get the 1ile .escriptor,
2ind/0))$hat port am I on&
connect/0))He"+ "ou,
listen/0))$ill some2od" please call me&
accept/0))3'han% "ou for calling port 4567.3
send/0 and rec!/0))'al% to me+ 2a2",
sendto/0 and rec!from/0))'al% to me+ .G8-M)st"le
close/0 and shutdown/0))Get outta m" face,
getpeername/0))$ho are "ou&
gethostname/0))$ho am I&
.())9ou sa" 3whitehouse.go!3+ I sa" 3:6;.:4<.=57.:773
Client)(er!er >ac%ground
- (imple (tream (er!er
- (imple (tream Client
.atagram (oc%ets
>loc%ing
select/0))("nchronous I?@ Multiplexing. Cool,
More references
.isclaimer and Call for Help
:
$hat is a soc%et&
A!er"thing in Unix is a file, $hat that person ma" ha!e 2een tal%ing a2out is the
fact that when Unix programs do an" sort of I?@+ the" do it 2" reading or writing to a
file descriptor. - file descriptor is simpl" an integer associated with an open file. >ut
/and here's the catch0+ that file can 2e a networ% connection+ a 1I1@+ a pipe+ a
terminal+ a real on)the)dis% file+ or Bust a2out an"thing else. A!er"thing in Unix is a
file, (o when "ou want to communicate with another program o!er the Internet
"ou're gonna do it through a file descriptor+ "ou'd 2etter 2elie!e it.
3$here do I get this file descriptor for networ% communication+ Mr. (mart")Pants&3
is pro2a2l" the last Cuestion on "our mind right now+ 2ut I'm going to answer it
an"wa"# 9ou ma%e a call to the soc%et/0 s"stem routine. It returns the soc%et
descriptor+ and "ou communicate through it using the specialiDed send/0 and rec!/0 /3man
send3+ 3man rec!30 soc%et calls.
If it's a file descriptor+ wh" in the hell can't I Bust use the normal read/0 and write/0 calls
to communicate through the soc%et&3 'he short answer is+ 39ou can,3 'he longer
answer is+ 39ou can+ 2ut send/0 and rec!/0 offer much greater control o!er "our data
transmission.3
'here are all %inds of soc%ets. 'here are .-8P- Internet addresses /Internet
(oc%ets0+ path names on a local node /Unix (oc%ets0+ CCI'' X.=E addresses /X.=E
(oc%ets that "ou can safel" ignore0+ and pro2a2l" man" others depending on which
Unix fla!or "ou run. 'his document deals onl" with the first# Internet (oc%ets.
'wo '"pes of Internet (oc%ets
I'm onl" going to tal% a2out two t"pes here. Axcept for this sentence+ where I'm
going to tell "ou that 38aw (oc%ets3 are also !er" powerful and "ou should loo%
them up.
$hat are the two t"pes& @ne is 3(tream (oc%ets3F the other is 3.atagram (oc%ets3+
which ma" hereafter 2e referred to as 3(@C*G('8A-M3 and 3(@C*G.G8-M3+
respecti!el". .atagram soc%ets are sometimes called 3connectionless soc%ets3
/though the" can 2e connect/0'd if "ou reall" want. (ee connect/0+ 2elow.
=
(tream soc%ets are relia2le two)wa" connected communication streams. If "ou
output two items into the soc%et in the order 3:+ =3+ the" will arri!e in the order 3:+
=3 at the opposite end. 'he" will also 2e error free. -n" errors "ou do encounter are
figments of "our own deranged mind+ and are not to 2e discussed here.
$hat uses stream soc%ets& $ell+ "ou ma" ha!e heard of the telnet application+ "es& It
uses stream soc%ets. -ll the characters "ou t"pe need to arri!e in the same order "ou
t"pe them+ right& -lso+ $$$ 2rowsers use the H''P protocol which uses stream
soc%ets to get pages. Indeed+ if "ou telnet to a $$$ site on port ;7+ and t"pe 3GA'
pagename3+ it'll dump the H'ML 2ac% at "ou,
(tream soc%ets achie!e this high le!el of data transmission Cualit" 2" using protocol
called 3'he 'ransmission Control Protocol3+ otherwise %nown as 3'CP3 . 'CP
ma%es sure "our data arri!es seCuentiall" and error)free. 9ou ma" ha!e heard 3'CP3
2efore as the 2etter half of 3'CP?IP3 where 3IP3 stands for 3Internet Protocol3/ IP
deals with Internet routing onl".0
$hat a2out .atagram soc%ets& $h" are the" called connectionless& $hat is the
deal+ here+ an"wa"& $h" are the" unrelia2le& $ell+ here are some facts# if "ou send
a datagram+ it ma" arri!e. It ma" arri!e out of order. If it arri!es+ the data within the
pac%et will 2e error)free.
.atagram soc%ets also use IP for routing+ 2ut the" don't use 'CPF the" use the 3User
.atagram Protocol3+ or 3U.P3
$h" are the" connectionless& $ell+ 2asicall"+ it's 2ecause "ou don't ha!e to maintain
an open connection as "ou do with stream soc%ets. 9ou Bust 2uild a pac%et+ slap an
IP header on it with destination information+ and send it out. o connection needed.
'he" are generall" used for pac%et)2")pac%et transfers of information. (ample
applications# tftp+ 2ootp+ etc.
How do these programs e!en wor% if datagrams might get lost&,3 $ell+ m" human
friend+ each has it's own protocol on top of U.P. 1or example+ the tftp protocol sa"s
that for each pac%et that gets sent+ the recipient has to send 2ac% a pac%et that sa"s+
3I got it,3 /an 3-C*3 pac%et.0 If the sender of the original pac%et gets no repl" in+
sa"+ fi!e seconds+ he'll re)transmit the pac%et until he finall" gets an -C*. 'his
ac%nowledgment procedure is !er" important when implementing (@C*G.G8-M
applications.
Low le!el onsense and etwor% 'heor"
4
(ince I Bust mentioned la"ering of protocols+ it's time to tal% a2out how
networ%s reall" wor%+ and to show some examples of how (@C*G.G8-M
pac%ets are 2uilt. Practicall"+ "ou can pro2a2l" s%ip this section. It's good
2ac%ground+ howe!er.
He"+ %ids+ it's time to learn a2out .ata Ancapsulation, 'his is !er" !er"
important. It's so important that "ou might Bust learn a2out it if "ou ta%e the
networ%s course here at Chico (tate F)0. >asicall"+ it sa"s this# a pac%et is 2orn+
the pac%et is wrapped /3encapsulated30 in a header /and ma"2e footer0 2" the first
protocol /sa"+ the '1'P protocol0+ then the whole thing /'1'P header included0 is
encapsulated again 2" the next protocol /sa"+ U.P0+ then again 2" the next /IP0+ then
again 2" the final protocol on the hardware /ph"sical0 la"er /sa"+ Athernet0.
$hen another computer recei!es the pac%et+ the hardware strips the Athernet header+
the %ernel strips the IP and U.P headers+ the '1'P program strips the '1'P header+
and it finall" has the data.
ow I can finall" tal% a2out the infamous La"ered etwor% Model. 'his etwor%
Model descri2es a s"stem of networ% functionalit" that has man" ad!antages o!er
other models. 1or instance+ "ou can write soc%ets programs that are exactl" the same
without caring how the data is ph"sicall" transmitted /serial+ thin Athernet+ -UI+
whate!er0 2ecause programs on lower le!els deal with it for "ou. 'he actual networ%
hardware and topolog" is transparent to the soc%et programmer.
$ithout an" further ado+ I'll present the la"ers of the full)2lown model. 8emem2er
this for networ% class exams#
-pplication
Presentation
(ession
'ransport
etwor%
.ata Lin%
Ph"sical
'he Ph"sical La"er is the hardware /serial+ Athernet+ etc.0. 'he -pplication La"er is
Bust a2out as far from the ph"sical la"er as "ou can imagine))it's the place where
users interact with the networ%.
ow+ this model is so general "ou could pro2a2l" use it as an automo2ile repair
guide if "ou reall" wanted to. - la"ered model more consistent with Unix might 2e#
5
-pplication La"er /telnet+ ftp+ etc.0
Host)to)Host 'ransport La"er /'CP+ U.P0
Internet La"er /IP and routing0
etwor% -ccess La"er /was etwor%+ .ata Lin%+ and Ph"sical0
-t this point in time+ "ou can pro2a2l" see how these la"ers correspond to the
encapsulation of the original data.
(ee how much wor% there is in 2uilding a simple pac%et& HeeD, -nd "ou ha!e to t"pe
in the pac%et headers "ourself using 3cat3, Hust %idding. -ll "ou ha!e to do for stream
soc%ets is send/0 the data out. -ll "ou ha!e to do for datagram soc%ets is encapsulate
the pac%et in the method of "our choosing and sendto/0 it out. 'he %ernel 2uilds the
'ransport La"er and Internet La"er on for "ou and the hardware does the etwor%
-ccess La"er. -h+ modern technolog".
(o ends our 2rief fora" into networ% theor". @h "es+ I forgot to tell "ou e!er"thing I
wanted to sa" a2out routing# nothing, 'hat's right+ I'm not going to tal% a2out it at
all. 'he router strips the pac%et to the IP header+ consults its routing ta2le+ 2lah 2lah
2lah. Chec% out the IP 81C if "ou reall" reall" care. If "ou ne!er learn a2out it+ well+
"ou'll li!e.
structs
$ell+ we're finall" here. It's time to tal% a2out programming. In this section+ I'll
co!er !arious data t"pes used 2" the soc%ets interface+ since some of them are a real
2itch to figure out.
1irst the eas" one# a soc%et descriptor. - soc%et descriptor is the following t"pe#
int
Hust a regular int.
'hings get weird from here+ so Bust read through and 2ear with me. *now this# there
are two 2"te orderings# most significant 2"te /sometimes called an 3octet30 first+ or
least significant 2"te first. 'he former is called 3etwor% >"te @rder3. (ome
machines store their num2ers internall" in etwor% >"te @rder+ some don't. $hen I
sa" something has to 2e in >@+ "ou ha!e to call a function /such as htons/00 to
change it from 3Host >"te @rder3. If I don't sa" 3>@3+ then "ou must lea!e the
!alue in Host >"te @rder.
E
M" 1irst (truct/'M0))struct soc%addr. 'his structure holds soc%et address information
for man" t"pes of soc%ets#
struct soc%addr I
unsigned short saGfamil"F ?J address famil"+ -1Gxxx J?
char saGdataK:5LF ?J :5 2"tes of protocol address J?
MF
saGfamil" can 2e a !ariet" of things+ 2ut it'll 2e 3-1GIA'3 for e!er"thing we do in this
document. saGdata contains a destination address and port num2er for the soc%et. 'his
is rather unwield".
'o deal with struct soc%addr+ programmers created a parallel structure# struct soc%addrGin
/3in3 for 3Internet3.0
struct soc%addrGin I
short int sinGfamil"F ?J -ddress famil" J?
unsigned short int sinGportF ?J Port num2er J?
struct inGaddr sinGaddrF ?J Internet address J?
unsigned char sinGDeroK;LF ?J (ame siDe as struct soc%addr J?
MF
'his structure ma%es it eas" to reference elements of the soc%et address. ote that
sinGDero /which is included to pad the structure to the length of a struct soc%addr0 should
2e set to all Deros with the function 2Dero/0 or memset/0. -lso+ and this is the important
2it+ a pointer to a struct soc%addrGin can 2e cast to a pointer to a struct soc%addr and !ice)
!ersa. (o e!en though soc%et/0 wants a struct soc%addr J+ "ou can still use a struct soc%addrGin
and cast it at the last minute, -lso+ notice that sinGfamil" corresponds to saGfamil" in a
struct soc%addr and should 2e set to 3-1GIA'3. 1inall"+ the sinGport and sinGaddr must 2e in
etwor% >"te @rder,
3>ut+3 "ou o2Bect+ 3how can the entire structure+ struct inGaddr sinGaddr+ 2e in etwor%
>"te @rder&3 'his Cuestion reCuires careful examination of the structure struct inGaddr+
one of the worst unions ali!e#
?J Internet address /a structure for historical reasons0 J?
struct inGaddr I
unsigned long sGaddrF
MF
$ell+ it used to 2e a union+ 2ut now those da"s seem to 2e gone. Good riddance. (o
if "ou ha!e declared 3ina3 to 2e of t"pe struct soc%addrGin+ then 3ina.sinGaddr.sGaddr3
references the 5 2"te IP address /in etwor% >"te @rder0. ote that e!en if "our
s"stem still uses the God)awful union for struct inGaddr+ "ou can still reference the 5
2"te IP address in exactl" the same wa" as I did a2o!e /this due to Ndefines.0
O
Con!ert the ati!es,
$e'!e now 2een lead right into the next section. 'here's 2een too much tal% a2out
this etwor% to Host >"te @rder con!ersion))now is the time for action,
-ll right". 'here are two t"pes that "ou can con!ert# short /two 2"tes0 and long /four
2"tes0. 'hese functions wor% for the unsigned !ariations as well. (a" "ou want to
con!ert a short from Host >"te @rder to etwor% >"te @rder. (tart with 3h3 for
3host3+ follow it with 3to3+ then 3n3 for 3networ%3+ and 3s3 for 3short3# h)to)n)s+ or
htons/0 /read# 3Host to etwor% (hort30.
It's almost too eas"...
9ou can use e!er" com2ination if 3n3+ 3h3+ 3s3+ and 3l3 "ou want+ not counting the
reall" stupid ones. 1or example+ there is @' a stolh/0 /3(hort to Long Host30
function))not at this part"+ an"wa". >ut there are#
htons/0))3Host to etwor% (hort3
htonl/0))3Host to etwor% Long3
ntohs/0))3etwor% to Host (hort3
ntohl/0))3etwor% to Host Long3
ow+ "ou ma" thin% "ou're wising up to this. 9ou might thin%+ 3$hat do I do if I
ha!e to change 2"te order on a char&3 'hen "ou might thin%+ 3Uh+ ne!er mind.3 9ou
might also thin% that since "our O;777 machine alread" uses networ% 2"te order+ "ou
don't ha!e to call htonl/0 on "our IP addresses. 9ou would 2e right+ >U' if "ou tr" to
port to a machine that has re!erse networ% 2"te order+ "our program will fail. >e
porta2le, 'his is a Unix world, 8emem2er# put "our 2"tes in etwor% @rder 2efore
"ou put them on the networ%.
- final point# wh" do sinGaddr and sinGport need to 2e in etwor% >"te @rder in a struct
soc%addrGin+ 2ut sinGfamil" does not& 'he answer# sinGaddr and sinGport get encapsulated in
the pac%et at the IP and U.P la"ers+ respecti!el". 'hus+ the" must 2e in etwor%
>"te @rder. Howe!er+ the sinGfamil" field is onl" used 2" the %ernel to determine what
t"pe of address the structure contains+ so it must 2e in Host >"te @rder. -lso+ since
sinGfamil" does not get sent out on the networ%+ it can 2e in Host >"te @rder.
IP -ddresses and How to .eal $ith 'hem
<
1ortunatel" for "ou+ there are a 2unch of functions that allow "ou to manipulate IP
addresses. o need to figure them out 2" hand and stuff them in a long with the PP
operator.
1irst+ let's sa" "ou ha!e a struct soc%addrGin ina+ and "ou ha!e an IP address
3:4=.=5:.E.:73 that "ou want to store into it. 'he function "ou want to use+ inetGaddr/0+
con!erts an IP address in num2ers)and)dots notation into an unsigned long. 'he
assignment can 2e made as follows#
ina.sinGaddr.sGaddr Q inetGaddr/3:4=.=5:.E.:730F
otice that inetGaddr/0 returns the address in etwor% >"te @rder alread"))"ou don't
ha!e to call htonl/0. (well,
ow+ the a2o!e code snippet isn't !er" ro2ust 2ecause there is no error chec%ing.
(ee+ inetGaddr/0 returns ): on error. 8emem2er 2inar" num2ers& /unsigned0): Bust happens
to correspond to the IP address =EE.=EE.=EE.=EE, 'hat's the 2roadcast address,
$rongo. 8emem2er to do "our error chec%ing properl".
-ll right+ now "ou can con!ert string IP addresses to longs. $hat a2out the other wa"
around& $hat if "ou ha!e a struct inGaddr and "ou want to print it in num2ers)and)dots
notation& In this case+ "ou'll want to use the function inetGntoa/0 /3ntoa3 means
3networ% to ascii30 li%e this#
printf/3Rs3+inetGntoa/ina.sinGaddr00F
'hat will print the IP address. ote that inetGntoa/0 ta%es a struct inGaddr as an argument+
not a long. -lso notice that it returns a pointer to a char. 'his points to a staticall"
stored char arra" within inetGntoa/0 so that each time "ou call inetGntoa/0 it will o!erwrite
the last IP address "ou as%ed for. 1or example#
char Ja:+ Ja=F
.
.
a: Q inetGntoa/ina:.sinGaddr0F ?J this is :6;.6=.:=6.: J?
a= Q inetGntoa/ina=.sinGaddr0F ?J this is :4=.=5:.E.:7 J?
printf/3address :# RsSn3+a:0F
printf/3address =# RsSn3+a=0F
will print#
address :# :4=.=5:.E.:7
address =# :4=.=5:.E.:7
If "ou need to sa!e the address+ strcp"/0 it to "our own character arra".
'hat's all on this topic for now. Later+ "ou'll learn to con!ert a string li%e
3whitehouse.go!3 into its corresponding IP address /see .(+ 2elow.0
;
soc%et/0))Get the 1ile .escriptor,
I guess I can put it off no longer))I ha!e to tal% a2out the soc%et/0 s"stem call. Here's
the 2rea%down#
Ninclude Ps"s?t"pes.hT
Ninclude Ps"s?soc%et.hT
int soc%et/int domain+ int t"pe+ int protocol0F
>ut what are these arguments& 1irst+ domain should 2e set to 3-1GIA'3+ Bust li%e in the
struct soc%addrGin /a2o!e.0 ext+ the t"pe argument tells the %ernel what %ind of soc%et
this is# (@C*G('8A-M or (@C*G.G8-M. 1inall"+ Bust set protocol to 373. /otes# there are
man" more domains than I'!e listed. 'here are man" more t"pes than I'!e listed. (ee the
soc%et/0 man page. -lso+ there's a 32etter3 wa" to get the protocol. (ee the getproto2"name/0 man
page.0
soc%et/0 simpl" returns to "ou a soc%et descriptor that "ou can use in later s"stem calls+
or ): on error. 'he glo2al !aria2le errno is set to the error's !alue /see the perror/0 man
page.0
2ind/0))$hat port am I on&
@nce "ou ha!e a soc%et+ "ou might ha!e to associate that soc%et with a port on "our
local machine. /'his is commonl" done if "ou're going to listen/0 for incoming
connections on a specific port))MU.s do this when the" tell "ou to 3telnet to x.".D
port O6O63.0 If "ou're going to onl" 2e doing a connect/0+ this ma" 2e unnecessar".
8ead it an"wa"+ Bust for %ic%s.
Here is the s"nopsis for the 2ind/0 s"stem call#
Ninclude Ps"s?t"pes.hT
Ninclude Ps"s?soc%et.hT
int 2ind/int soc%fd+ struct soc%addr Jm"Gaddr+ int addrlen0F
soc%fd is the soc%et file descriptor returned 2" soc%et/0. m"Gaddr is a pointer to a struct
soc%addr that contains information a2out "our address+ namel"+ port and IP address.
addrlen can 2e set to siDeof/struct soc%addr0.
$hew. 'hat's a 2it to a2sor2 in one chun%. Let's ha!e an example#
6
Ninclude Pstring.hT
Ninclude Ps"s?t"pes.hT
Ninclude Ps"s?soc%et.hT
Ndefine M9P@8' 4567
main/0
I
int soc%fdF
struct soc%addrGin m"GaddrF
soc%fd Q soc%et/-1GIA'+ (@C*G('8A-M+ 70F ?J do some error chec%ing, J?
m"Gaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
m"Gaddr.sinGport Q htons/M9P@8'0F ?J short+ networ% 2"te order J?
m"Gaddr.sinGaddr.sGaddr Q inetGaddr/3:4=.=5:.E.:730F
2Dero/U/m"Gaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
?J don't forget "our error chec%ing for 2ind/0# J?
2ind/soc%fd+ /struct soc%addr J0Um"Gaddr+ siDeof/struct soc%addr00F
.
.
.
'here are a few things to notice here. m"Gaddr.sinGport is in etwor% >"te @rder. (o is
m"Gaddr.sinGaddr.sGaddr. -nother thing to watch out for is that the header files might differ
from s"stem to s"stem. 'o 2e sure+ "ou should chec% "our local man pages.
Lastl"+ on the topic of 2ind/0+ I should mention that some of the process of getting
"our own IP address and?or port can can 2e automated#
m"Gaddr.sinGport Q 7F ?J choose an unused port at random J?
m"Gaddr.sinGaddr.sGaddr Q I-..8G-9F ?J use m" IP address J?
(ee+ 2" setting m"Gaddr.sinGport to Dero+ "ou are telling 2ind/0 to choose the port for "ou.
Li%ewise+ 2" setting m"Gaddr.sinGaddr.sGaddr to I-..8G-9+ "ou are telling it to
automaticall" fill in the IP address of the machine the process is running on.
If "ou are into noticing little things+ "ou might ha!e seen that I didn't put I-..8G-9
into etwor% >"te @rder, aught" me. Howe!er+ I ha!e inside info# I-..8G-9 is
reall" Dero, Vero still has Dero on 2its e!en if "ou rearrange the 2"tes. Howe!er+
purists will point out that there could 2e a parallel dimension where I-..8G-9 is+
sa"+ := and that m" code won't wor% there. 'hat's o% with me#
m"Gaddr.sinGport Q htons/70F ?J choose an unused port at random J?
:7
m"Gaddr.sinGaddr.sGaddr Q htonl/I-..8G-90F ?J use m" IP address J?
ow we're so porta2le "ou pro2a2l" wouldn't 2elie!e it. I Bust wanted to point that
out+ since most of the code "ou come across won't 2other running I-..8G-9
through htonl/0.
2ind/0 also returns ): on error and sets errno to the error's !alue.
-nother thing to watch out for when calling 2ind/0# don't go under2oard with "our
port num2ers. -ll ports 2elow :7=5 are 8A(A8WA., 9ou can ha!e an" port num2er
a2o!e that+ right up to OEE4E /pro!ided the" aren't alread" 2eing used 2" another
program.0
@ne small extra final note a2out 2ind/0# there are times when "ou won't a2solutel"
ha!e to call it. If "ou are connect/0'ing to a remote machine and "ou don't care what
"our local port is /as is the case with telnet0+ "ou can simpl" call connect/0+ it'll chec% to
see if the soc%et is un2ound+ and will 2ind/0 it to an unused local port.
connect/0))He"+ "ou,
Let's Bust pretend for a few minutes that "ou're a telnet application. 9our user
commands "ou /Bust li%e in the mo!ie '8@0 to get a soc%et file descriptor. 9ou
compl" and call soc%et/0. ext+ the user tells "ou to connect to 3:4=.=5:.E.:73 on port
3=43 /the standard telnet port.0 @h m" God, $hat do "ou do now&
Luc%" for "ou+ program+ "ou're now perusing the section on connect/0))how to connect
to a remote host. 9ou read furiousl" onward+ not wanting to disappoint "our user...
'he connect/0 call is as follows#
Ninclude Ps"s?t"pes.hT
Ninclude Ps"s?soc%et.hT
int connect/int soc%fd+ struct soc%addr Jser!Gaddr+ int addrlen0F
soc%fd is our friendl" neigh2orhood soc%et file descriptor+ as returned 2" the soc%et/0
call+ ser!Gaddr is a struct soc%addr containing the destination port and IP address+ and addrlen
can 2e set to siDeof/struct soc%addr0.
Isn't this starting to ma%e more sense& Let's ha!e an example#
Ninclude Pstring.hT
Ninclude Ps"s?t"pes.hT
::
Ninclude Ps"s?soc%et.hT
Ndefine .A('GIP 3:4=.=5:.E.:73
Ndefine .A('GP@8' =4
main/0
I
int soc%fdF
struct soc%addrGin destGaddrF ?J will hold the destination addr J?
soc%fd Q soc%et/-1GIA'+ (@C*G('8A-M+ 70F ?J do some error chec%ing, J?
destGaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
destGaddr.sinGport Q htons/.A('GP@8'0F ?J short+ networ% 2"te order J?
destGaddr.sinGaddr.sGaddr Q inetGaddr/.A('GIP0F
2Dero/U/destGaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
?J don't forget to error chec% the connect/0, J?
connect/soc%fd+ /struct soc%addr J0UdestGaddr+ siDeof/struct soc%addr00F
.
.
.
-gain+ 2e sure to chec% the return !alue from connect/0))it'll return ): on error and set
the !aria2le errno.
-lso+ notice that we didn't call 2ind/0. >asicall"+ we don't care a2out our local port
num2erF we onl" care where we're going. 'he %ernel will choose a local port for us+
and the site we connect to will automaticall" get this information from us. o
worries.
listen/0))$ill some2od" please call me&
@%+ time for a change of pace. $hat if "ou don't want to connect to a remote host.
(a"+ Bust for %ic%s+ that "ou want to wait for incoming connections and handle them
in some wa". 'he process is two step# first "ou listen/0+ then "ou accept/0 /see 2elow.0
'he listen call is fairl" simple+ 2ut reCuires a 2it of explanation#
int listen/int soc%fd+ int 2ac%log0F
:=
soc%fd is the usual soc%et file descriptor from the soc%et/0 s"stem call. 2ac%log is the
num2er of connections allowed on the incoming Cueue. $hat does that mean& $ell+
incoming connections are going to wait in this Cueue until "ou accept/0 them /see
2elow0 and this is the limit on how man" can Cueue up. Most s"stems silentl" limit
this num2er to a2out =7F "ou can pro2a2l" get awa" with setting it to E or :7.
-gain+ as per usual+ listen/0 returns ): and sets errno on error.
$ell+ as "ou can pro2a2l" imagine+ we need to call 2ind/0 2efore we call listen/0 or the
%ernel will ha!e us listening on a random port. >leah, (o if "ou're going to 2e
listening for incoming connections+ the seCuence of s"stem calls "ou'll ma%e is#
soc%et/0F
2ind/0F
listen/0F
?J accept/0 goes here J?
I'll Bust lea!e that in the place of sample code+ since it's fairl" self)explanator". /'he
code in the accept/0 section+ 2elow+ is more complete.0 'he reall" tric%" part of this
whole sha)2ang is the call to accept/0.
accept/0))3'han% "ou for calling port 4567.3
Get read"))the accept/0 call is %inda weird, $hat's going to happen is this# someone far
far awa" will tr" to connect/0 to "our machine on a port that "ou are listen/0'ing on. 'heir
connection will 2e Cueued up waiting to 2e accept/0'ed. 9ou call accept/0 and "ou tell it
to get the pending connection. It'll return to "ou a 2rand new soc%et file descriptor to
use for this single connection, 'hat's right+ suddenl" "ou ha!e two soc%et file
descriptors for the price of one, 'he original one is still listening on "our port and
the newl" created one is finall" read" to send/0 and rec!/0. $e're there,
'he call is as follows#
Ninclude Ps"s?soc%et.hT
int accept/int soc%fd+ !oid Jaddr+ int Jaddrlen0F
soc%fd is the listen/0'ing soc%et descriptor. Aas" enough. addr will usuall" 2e a pointer to
a local struct soc%addrGin. 'his is where the information a2out the incoming connection
will go /and "ou can determine which host is calling "ou from which port0. addrlen is
a local integer !aria2le that should 2e set to siDeof/struct soc%addrGin0 2efore its address is
passed to accept/0. -ccept will not put more than that man" 2"tes into addr. If it puts
fewer in+ it'll change the !alue of addrlen to reflect that.
:4
Guess what& accept/0 returns ): and sets errno if an error occurs. >etcha didn't figure
that.
Li%e 2efore+ this is a 2unch to a2sor2 in one chun%+ so here's a sample code fragment
for "our perusal#
Ninclude Pstring.hT
Ninclude Ps"s?t"pes.hT
Ninclude Ps"s?soc%et.hT
Ndefine M9P@8' 4567 ?J the port users will 2e connecting to J?
Ndefine >-C*L@G :7 ?J how man" pending connections Cueue will hold J?
main/0
I
int soc%fd+ newGfdF ?J listen on soc%Gfd+ new connection on newGfd J?
struct soc%addrGin m"GaddrF ?J m" address information J?
struct soc%addrGin theirGaddrF ?J connector's address information J?
int sinGsiDeF
soc%fd Q soc%et/-1GIA'+ (@C*G('8A-M+ 70F ?J do some error chec%ing, J?
m"Gaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
m"Gaddr.sinGport Q htons/M9P@8'0F ?J short+ networ% 2"te order J?
m"Gaddr.sinGaddr.sGaddr Q I-..8G-9F ?J auto)fill with m" IP J?
2Dero/U/m"Gaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
?J don't forget "our error chec%ing for these calls# J?
2ind/soc%fd+ /struct soc%addr J0Um"Gaddr+ siDeof/struct soc%addr00F
listen/soc%fd+ >-C*L@G0F
sinGsiDe Q siDeof/struct soc%addrGin0F
newGfd Q accept/soc%fd+ UtheirGaddr+ UsinGsiDe0F
.
.
.
-gain+ note that we will use the soc%et descriptor newGfd for all send/0 and rec!/0 calls. If
"ou're onl" getting one single connection e!er+ "ou can close/0 the original soc%fd in
order to pre!ent more incoming connections on the same port+ if "ou so desire.
:5
send/0 and rec!/0))'al% to me+ 2a2",
'hese two functions are for communicating o!er stream soc%ets or connected
datagram soc%ets. If "ou want to use regular unconnected datagram soc%ets+ "ou'll
need to see the section on sendto/0 and rec!from/0+ 2elow.
'he send/0 call#
int send/int soc%fd+ const !oid Jmsg+ int len+ int flags0F
soc%fd is the soc%et descriptor "ou want to send data to /whether it's the one returned
2" soc%et/0 or the one "ou got with accept/0.0 msg is a pointer to the data "ou want to
send+ and len is the length of that data in 2"tes. Hust set flags to 7. /(ee the send/0 man page
for more information concerning flags.0
(ome sample code might 2e#
char Jmsg Q 3>eeB was here,3F
int len+ 2"tesGsentF
.
.
len Q strlen/msg0F
2"tesGsent Q send/soc%fd+ msg+ len+ 70F
.
.
.
send/0 returns the num2er of 2"tes actuall" sent out))this might 2e less than the
num2er "ou told it to send, (ee+ sometimes "ou tell it to send a whole go2 of data
and it Bust can't handle it. It'll fire off as much of the data as it can+ and trust "ou to
send the rest later. 8emem2er+ if the !alue returned 2" send/0 doesn't match doesn't
match the !alue in len+ it's up to "ou to send the rest of the string. 'he good news is
this# if the pac%et is small /less than :* or so0 it will pro2a2l" manage to send the
whole thing all in one go. -gain+ ): is returned on error+ and errno is set to the error
num2er.
'he rec!/0 call is similar in man" respects#
int rec!/int soc%fd+ !oid J2uf+ int len+ unsigned int flags0F
soc%fd is the soc%et descriptor to read from+ 2uf is the 2uffer to read the information
into+ len is the maximum length of the 2uffer+ and flags can again 2e set to 7. /(ee the
rec!/0 man page for flag information.0
rec!/0 returns the num2er of 2"tes actuall" read into the 2uffer+ or ): on error /with errno
set+ accordingl".0
:E
'here+ that was eas"+ wasn't it& 9ou can now pass data 2ac% and forth on stream
soc%ets, $hee, 9ou're a Unix etwor% Programmer,
sendto/0 and rec!from/0))'al% to me+ .G8-M)st"le
3'his is all fine and dand"+3 I hear "ou sa"ing+ 32ut where does this lea!e me with
unconnected datagram soc%ets&3 o pro2lemo+ amigo. $e ha!e Bust the thing.
(ince datagram soc%ets aren't connected to a remote host+ guess which piece of
information we need to gi!e 2efore we send a pac%et& 'hat's right, 'he destination
address, Here's the scoop#
int sendto/int soc%fd+ const !oid Jmsg+ int len+ unsigned int flags+
const struct soc%addr Jto+ int tolen0F
-s "ou can see+ this call is 2asicall" the same as the call to send/0 with the addition of
two other pieces of information. to is a pointer to a struct soc%addr /which "ou'll pro2a2l"
ha!e as a struct soc%addrGin and cast it at the last minute0 which contains the destination
IP address and port. tolen can simpl" 2e set to siDeof/struct soc%addr0.
Hust li%e with send/0+ sendto/0 returns the num2er of 2"tes actuall" sent /which+ again+
might 2e less than the num2er of 2"tes "ou told it to send,0+ or ): on error.
ACuall" similar are rec!/0 and rec!from/0. 'he s"nopsis of rec!from/0 is#
int rec!from/int soc%fd+ !oid J2uf+ int len+ unsigned int flags
struct soc%addr Jfrom+ int Jfromlen0F
-gain+ this is Bust li%e rec!/0 with the addition of a couple fields. from is a pointer to a
local struct soc%addr that will 2e filled with the IP address and port of the originating
machine. fromlen is a pointer to a local int that should 2e initialiDed to siDeof/struct soc%addr0.
$hen the function returns+ fromlen will contain the length of the address actuall"
stored in from.
rec!from/0 returns the num2er of 2"tes recei!ed+ or ): on error /with errno set
accordingl".0
8emem2er+ if "ou connect/0 a datagram soc%et+ "ou can then simpl" use send/0 and rec!/0
for all "our transactions. 'he soc%et itself is still a datagram soc%et and the pac%ets
still use U.P+ 2ut the soc%et interface will automaticall" add the destination and
source information for "ou.
:O
close/0 and shutdown/0))Get outta m" face,
$hew, 9ou'!e 2een send/0'ing and rec!/0'ing data all da" long+ and "ou'!e had it. 9ou're
read" to close the connection on "our soc%et descriptor. 'his is eas". 9ou can Bust
use the regular Unix file descriptor close/0 function#
close/soc%fd0F
'his will pre!ent an" more reads and writes to the soc%et. -n"one attempting to read
or write the soc%et on the remote end will recei!e an error.
Hust in case "ou want a little more control o!er how the soc%et closes+ "ou can use
the shutdown/0 function. It allows "ou to cut off communication in a certain direction+
or 2oth wa"s /Bust li%e close/0 does.0 ("nopsis#
int shutdown/int soc%fd+ int how0F
soc%fd is the soc%et file descriptor "ou want to shutdown+ and how is one of the
following#
7 ) 1urther recei!es are disallowed
: ) 1urther sends are disallowed
= ) 1urther sends and recei!es are disallowed /li%e close/00
shutdown/0 returns 7 on success+ and ): on error /with errno set accordingl".0
If "ou deign to use shutdown/0 on unconnected datagram soc%ets+ it will simpl" ma%e
the soc%et una!aila2le for further send/0 and rec!/0 calls /remem2er that "ou can use
these if "ou connect/0 "our datagram soc%et.0
othing to it.
getpeername/0))$ho are "ou&
'his function is so eas".
It's so eas"+ I almost didn't gi!e it it's own section. >ut here it is an"wa".
'he function getpeername/0 will tell "ou who is at the other end of a connected stream
soc%et. 'he s"nopsis#
Ninclude Ps"s?soc%et.hT
int getpeername/int soc%fd+ struct soc%addr Jaddr+ int Jaddrlen0F
:<
soc%fd is the descriptor of the connected stream soc%et+ addr is a pointer to a struct soc%addr
/or a struct soc%addrGin0 that will hold the information a2out the other side of the
connection+ and addrlen is a pointer to an int+ that should 2e initialiDed to siDeof/struct
soc%addr0.
'he function returns ): on error and sets errno accordingl".
@nce "ou ha!e their address+ "ou can use inetGntoa/0 or gethost2"addr/0 to print or get more
information. o+ "ou can't get their login name. /@%+ o%. If the other computer is
running an ident daemon+ this is possi2le. 'his+ howe!er+ is 2e"ond the scope of this
document. Chec% out 81C):5:4 for more info.0
gethostname/0))$ho am I&
A!en easier than getpeername/0 is the function gethostname/0. It returns the name of the
computer that "our program is running on. 'he name can then 2e used 2"
gethost2"name/0+ 2elow+ to determine the IP address of "our local machine.
$hat could 2e more fun& I could thin% of a few things+ 2ut the" don't pertain to
soc%et programming. -n"wa"+ here's the 2rea%down#
Ninclude Punistd.hT
int gethostname/char Jhostname+ siDeGt siDe0F
'he function returns 7 on successful completion+ and ): on error+ setting errno as usual.
.
.())9ou sa" 3whitehouse.go!3+ I sa" 3:6;.:4<.=57.:773
In case "ou don't %now what .( is+ it stands for 3.omain ame (er!ice3. In a
nutshell+ "ou tell it what the human)reada2le address is for a site+ and it'll gi!e "ou
the IP address /so "ou can use it with 2ind/0+ connect/0+ sendto/0+ or whate!er "ou need it
for.0 'his wa"+ when someone enters#
X telnet whitehouse.go!
telnet can find out that it needs to connect/0 to 3:6;.:4<.=57.:773.
>ut how does it wor%& 9ou'll 2e using the function gethost2"name/0#
:;
Ninclude Pnetd2.hT

struct hostent Jgethost2"name/const char Jname0F
-s "ou see+ it returns a pointer to a struct hostent+ the la"out of which is as follows#
struct hostent I
char JhGnameF
char JJhGaliasesF
int hGaddrt"peF
int hGlengthF
char JJhGaddrGlistF
MF
Ndefine hGaddr hGaddrGlistK7L
-nd here are the descriptions of the fields in the struct hostent#
hGname ) @fficial name of the host.
hGaliases ) - ULL)terminated arra" of alternate names for the host.
hGaddrt"pe ) 'he t"pe of address 2eing returnedF usuall" -1GIA'.
hGlength ) 'he length of the address in 2"tes.
hGaddrGlist ) - Dero)terminated arra" of networ% addresses for the host. Host
addresses are in etwor% >"te @rder.
hGaddr ) 'he first address in hGaddrGlist.
gethost2"name/0 returns a pointer to the filled struct hostent+ or ULL on error. />ut errno is
not set))hGerrno is set instead. (ee herror/0+ 2elow.0
>ut how is it used& (ometimes /as we find from reading computer manuals0+ Bust
spewing the information at the reader is not enough. 'his function is certainl" easier
to use than it loo%s.
Here's an example program#
Ninclude Pstdio.hT
Ninclude Pstdli2.hT
Ninclude Perrno.hT
Ninclude Pnetd2.hT
Ninclude Ps"s?t"pes.hT
Ninclude Pnetinet?in.hT
int main/int argc+ char Jarg!KL0
I
struct hostent JhF
if /argc ,Q =0 I ?J error chec% the command line J?
fprintf/stderr+3usage# getip addressSn30F
:6
exit/:0F
M
if //hQgethost2"name/arg!K:L00 QQ ULL0 I ?J get the host info J?
herror/3gethost2"name30F
exit/:0F
M
printf/3Host name # RsSn3+ h)ThGname0F
printf/3IP -ddress # RsSn3+inetGntoa/J//struct inGaddr J0h)ThGaddr000F
return 7F
M
$ith gethost2"name/0+ "ou can't use perror/0 to print error message /since errno is not used0.
Instead+ call herror/0.
It's prett" straightforward. 9ou simpl" pass the string that contains the machine
name /3whitehouse.go!30 to gethost2"name/0+ and then gra2 the information out of the
returned struct hostent.
'he onl" possi2le weirdness might 2e in the printing of the IP address+ a2o!e. h)
ThGaddr is a char J+ 2ut inetGntoa/0 wants a struct inGaddr passed to it. (o I cast h)ThGaddr to a
struct inGaddr J+ then dereference it to get at the data.
Client)(er!er >ac%ground
It's a client)ser!er world+ 2a2". Hust a2out e!er"thing on the networ% deals with
client processes tal%ing to ser!er processes and !ice)!ersa. 'a%e telnet+ for instance.
$hen "ou connect to a remote host on port =4 with telnet /the client0+ a program on
that host /called telnetd+ the ser!er0 springs to life. It handles the incoming telnet
connection+ sets "ou up with a login prompt+ etc.
=7
1igure =. 'he Client)(er!er 8elationship.
'he exchange of information 2etween client and ser!er is summariDed in 1igure =.
ote that the client)ser!er pair can spea% (@C*G('8A-M+ (@C*G.G8-M+ or an"thing
else /as long as the"'re spea%ing the same thing.0 (ome good examples of client)
ser!er pairs are telnet?telnetd+ ftp?ftpd+ or 2ootp?2ootpd. A!er" time "ou use ftp+ there's a
remote program+ ftpd+ that ser!es "ou.
@ften+ there will onl" 2e one ser!er on a machine+ and that ser!er will handle
multiple clients using for%/0. 'he 2asic routine is# ser!er will wait for a connection+
accept/0 it+ and for%/0 a child process to handle it. 'his is what our sample ser!er does in
the next section.
- (imple (tream (er!er
-ll this ser!er does is send the string 3Hello+ $orld,Sn3 out o!er a stream connection. -ll
"ou need to do to test this ser!er is run it in one window+ and telnet to it from
another with#
X telnet remotehostname 4567
where remotehostname is the name of the machine "ou're running it on.
'he ser!er code# /ote# a trailing 2ac%slash on a line means that the line is continued on
the next.0
Ninclude Pstdio.hT
Ninclude Pstdli2.hT
Ninclude Perrno.hT
Ninclude Pstring.hT
Ninclude Ps"s?t"pes.hT
Ninclude Pnetinet?in.hT
=:
Ninclude Ps"s?soc%et.hT
Ninclude Ps"s?wait.hT
Ndefine M9P@8' 4567 ?J the port users will 2e connecting to J?
Ndefine >-C*L@G :7 ?J how man" pending connections Cueue will hold J?
main/0
I
int soc%fd+ newGfdF ?J listen on soc%Gfd+ new connection on newGfd J?
struct soc%addrGin m"GaddrF ?J m" address information J?
struct soc%addrGin theirGaddrF ?J connector's address information J?
int sinGsiDeF
if //soc%fd Q soc%et/-1GIA'+ (@C*G('8A-M+ 700 QQ ):0 I
perror/3soc%et30F
exit/:0F
M
m"Gaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
m"Gaddr.sinGport Q htons/M9P@8'0F ?J short+ networ% 2"te order J?
m"Gaddr.sinGaddr.sGaddr Q I-..8G-9F ?J auto)fill with m" IP J?
2Dero/U/m"Gaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
if /2ind/soc%fd+ /struct soc%addr J0Um"Gaddr+ siDeof/struct soc%addr00 S
QQ ):0 I
perror/32ind30F
exit/:0F
M
if /listen/soc%fd+ >-C*L@G0 QQ ):0 I
perror/3listen30F
exit/:0F
M
while/:0 I ?J main accept/0 loop J?
sinGsiDe Q siDeof/struct soc%addrGin0F
if //newGfd Q accept/soc%fd+ /struct soc%addr J0UtheirGaddr+ S
UsinGsiDe00 QQ ):0 I
perror/3accept30F
continueF
M
==
printf/3ser!er# got connection from RsSn3+ S
inetGntoa/theirGaddr.sinGaddr00F
if /,for%/00 I ?J this is the child process J?
if /send/newGfd+ 3Hello+ world,Sn3+ :5+ 70 QQ ):0
perror/3send30F
close/newGfd0F
exit/70F
M
close/newGfd0F ?J parent doesn't need this J?
while/waitpid/):+ULL+$@H-G0 T 70F ?J clean up child processes J?
M
M
In case "ou're curious+ I ha!e the code in one 2ig main/0 function for /I feel0 s"ntactic
clarit". 1eel free to split it into smaller functions if it ma%es "ou feel 2etter.
9ou can also get the string from this ser!er 2" using the client listed in the next
section.
- (imple (tream Client
'his gu"'s e!en easier than the ser!er. -ll this client does is connect to the host "ou
specif" on the command line+ port 4567. It gets the string that the ser!er sends.
'he client source#
Ninclude Pstdio.hT
Ninclude Pstdli2.hT
Ninclude Perrno.hT
Ninclude Pstring.hT
Ninclude Pnetd2.hT
Ninclude Ps"s?t"pes.hT
Ninclude Pnetinet?in.hT
Ninclude Ps"s?soc%et.hT
Ndefine P@8' 4567 ?J the port client will 2e connecting to J?
Ndefine M-X.-'-(IVA :77 ?J max num2er of 2"tes we can get at once J?
int main/int argc+ char Jarg!KL0
I
=4
int soc%fd+ num2"tesF
char 2ufKM-X.-'-(IVALF
struct hostent JheF
struct soc%addrGin theirGaddrF ?J connector's address information J?
if /argc ,Q =0 I
fprintf/stderr+3usage# client hostnameSn30F
exit/:0F
M
if //heQgethost2"name/arg!K:L00 QQ ULL0 I ?J get the host info J?
herror/3gethost2"name30F
exit/:0F
M
if //soc%fd Q soc%et/-1GIA'+ (@C*G('8A-M+ 700 QQ ):0 I
perror/3soc%et30F
exit/:0F
M
theirGaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
theirGaddr.sinGport Q htons/P@8'0F ?J short+ networ% 2"te order J?
theirGaddr.sinGaddr Q J//struct inGaddr J0he)ThGaddr0F
2Dero/U/theirGaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
if /connect/soc%fd+ /struct soc%addr J0UtheirGaddr+ S
siDeof/struct soc%addr00 QQ ):0 I
perror/3connect30F
exit/:0F
M
if //num2"tesQrec!/soc%fd+ 2uf+ M-X.-'-(IVA+ 700 QQ ):0 I
perror/3rec!30F
exit/:0F
M
2ufKnum2"tesL Q 'S7'F
printf/38ecei!ed# Rs3+2uf0F
close/soc%fd0F
=5
return 7F
M
otice that if "ou don't run the ser!er 2efore "ou run the client+ connect/0 returns
3Connection refused3. Wer" useful.
.atagram (oc%ets
I reall" don't ha!e that much to tal% a2out here+ so I'll Bust present a couple of sample
programs# tal%er.c and listener.c.
listener sits on a machine waiting for an incoming pac%et on port 56E7. tal%er sends a
pac%et to that port+ on the specified machine+ that contains whate!er the user enters
on the command line.
Here is the source for listener.c#
Ninclude Pstdio.hT
Ninclude Pstdli2.hT
Ninclude Perrno.hT
Ninclude Pstring.hT
Ninclude Ps"s?t"pes.hT
Ninclude Pnetinet?in.hT
Ninclude Ps"s?soc%et.hT
Ninclude Ps"s?wait.hT
Ndefine M9P@8' 56E7 ?J the port users will 2e sending to J?
Ndefine M-X>U1LA :77
main/0
I
int soc%fdF
struct soc%addrGin m"GaddrF ?J m" address information J?
struct soc%addrGin theirGaddrF ?J connector's address information J?
int addrGlen+ num2"tesF
char 2ufKM-X>U1LALF
if //soc%fd Q soc%et/-1GIA'+ (@C*G.G8-M+ 700 QQ ):0 I
perror/3soc%et30F
exit/:0F
=E
M
m"Gaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
m"Gaddr.sinGport Q htons/M9P@8'0F ?J short+ networ% 2"te order J?
m"Gaddr.sinGaddr.sGaddr Q I-..8G-9F ?J auto)fill with m" IP J?
2Dero/U/m"Gaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
if /2ind/soc%fd+ /struct soc%addr J0Um"Gaddr+ siDeof/struct soc%addr00 S
QQ ):0 I
perror/32ind30F
exit/:0F
M
addrGlen Q siDeof/struct soc%addr0F
if //num2"tesQrec!from/soc%fd+ 2uf+ M-X>U1LA+ 7+ S
/struct soc%addr J0UtheirGaddr+ UaddrGlen00 QQ ):0 I
perror/3rec!from30F
exit/:0F
M
printf/3got pac%et from RsSn3+inetGntoa/theirGaddr.sinGaddr00F
printf/3pac%et is Rd 2"tes longSn3+num2"tes0F
2ufKnum2"tesL Q 'S7'F
printf/3pac%et contains S3RsS3Sn3+2uf0F
close/soc%fd0F
M
otice that in our call to soc%et/0 we're finall" using (@C*G.G8-M. -lso+ note that
there's no need to listen/0 or accept/0. 'his is one of the per%s of using unconnected
datagram soc%ets,
ext comes the source for tal%er.c#
Ninclude Pstdio.hT
Ninclude Pstdli2.hT
Ninclude Perrno.hT
Ninclude Pstring.hT
Ninclude Ps"s?t"pes.hT
Ninclude Pnetinet?in.hT
Ninclude Pnetd2.hT
Ninclude Ps"s?soc%et.hT
Ninclude Ps"s?wait.hT
=O
Ndefine M9P@8' 56E7 ?J the port users will 2e sending to J?
int main/int argc+ char Jarg!KL0
I
int soc%fdF
struct soc%addrGin theirGaddrF ?J connector's address information J?
struct hostent JheF
int num2"tesF
if /argc ,Q 40 I
fprintf/stderr+3usage# tal%er hostname messageSn30F
exit/:0F
M
if //heQgethost2"name/arg!K:L00 QQ ULL0 I ?J get the host info J?
herror/3gethost2"name30F
exit/:0F
M
if //soc%fd Q soc%et/-1GIA'+ (@C*G.G8-M+ 700 QQ ):0 I
perror/3soc%et30F
exit/:0F
M
theirGaddr.sinGfamil" Q -1GIA'F ?J host 2"te order J?
theirGaddr.sinGport Q htons/M9P@8'0F ?J short+ networ% 2"te order J?
theirGaddr.sinGaddr Q J//struct inGaddr J0he)ThGaddr0F
2Dero/U/theirGaddr.sinGDero0+ ;0F ?J Dero the rest of the struct J?
if //num2"tesQsendto/soc%fd+ arg!K=L+ strlen/arg!K=L0+ 7+ S
/struct soc%addr J0UtheirGaddr+ siDeof/struct soc%addr000 QQ ):0 I
perror/3sendto30F
exit/:0F
M
printf/3sent Rd 2"tes to RsSn3+num2"tes+inetGntoa/theirGaddr.sinGaddr00F
close/soc%fd0F
return 7F
M
=<
-nd that's all there is to it, 8un listener on some machine+ then run tal%er on another.
$atch them communicate, 1un G)rated excitement for the entire nuclear famil",
Axcept for one more tin" detail that I'!e mentioned man" times in the past#
connected datagram soc%ets. I need to tal% a2out this here+ since we're in the
datagram section of the document. Let's sa" that tal%er calls connect/0 and specifies the
listener's address. 1rom that point on+ tal%er ma" onl" sent to and recei!e from the
address specified 2" connect/0. 1or this reason+ "ou don't ha!e to use sendto/0 and
rec!from/0F "ou can simpl" use send/0 and rec!/0.
>loc%ing
>loc%ing. 9ou'!e heard a2out it))now what the hell is it& In a nutshell+ 32loc%3 is
techie Bargon for 3sleep3. 9ou pro2a2l" noticed that when "ou run listener+ a2o!e+ it
Bust sits there until a pac%et arri!es. $hat happened is that it called rec!from/0+ there
was no data+ and so rec!from/0 is said to 32loc%3 /that is+ sleep there0 until some data
arri!es.
Lots of functions 2loc%. accept/0 2loc%s. -ll the rec!J/0 functions 2loc%. 'he reason the"
can do this is 2ecause the"'re allowed to. $hen "ou first create the soc%et descriptor
with soc%et/0+ the %ernel sets it to 2loc%ing. If "ou don't want a soc%et to 2e 2loc%ing+
"ou ha!e to ma%e a call to fcntl/0#
Ninclude Punistd.hT
Ninclude Pfcntl.hT
.
.
soc%fd Q soc%et/-1GIA'+ (@C*G('8A-M+ 70F
fcntl/soc%fd+ 1G(A'1L+ @G@>L@C*0F
.
.
>" setting a soc%et to non)2loc%ing+ "ou can effecti!el" 3poll3 the soc%et for
information. If "ou tr" to read from a non)2loc%ing soc%et and there's no data there+
it's not allowed to 2loc%))it will return ): and errno will 2e set to A$@UL.>L@C*.
Generall" spea%ing+ howe!er+ this t"pe of polling is a 2ad idea. If "ou put "our
program in a 2us")wait loo%ing for data on the soc%et+ "ou'll suc% up CPU time li%e
it was going out of st"le. - more elegant solution for chec%ing to see if there's data
waiting to 2e read comes in the following section on select/0.
=;
select/0))("nchronous I?@ Multiplexing
'his function is somewhat strange+ 2ut it's !er" useful. 'a%e the following situation#
"ou are a ser!er and "ou want to listen for incoming connections as well as %eep
reading from the connections "ou alread" ha!e.
o pro2lem+ "ou sa"+ Bust an accept/0 and a couple of rec!/0s. ot so fast+ 2uster, $hat
if "ou're 2loc%ing on an accept/0 call& How are "ou going to rec!/0 data at the same
time& 3Use non)2loc%ing soc%ets,3 o wa", 9ou don't want to 2e a CPU hog. $hat+
then&
select/0 gi!es "ou the power to monitor se!eral soc%ets at the same time. It'll tell "ou
which ones are read" for reading+ which are read" for writing+ and which soc%ets
ha!e raised exceptions+ if "ou reall" want to %now that.
$ithout an" further ado+ I'll offer the s"nopsis of select/0#
Ninclude Ps"s?time.hT
Ninclude Ps"s?t"pes.hT
Ninclude Punistd.hT
int select/int numfds+ fdGset Jreadfds+ fdGset Jwritefds+
fdGset Jexceptfds+ struct time!al Jtimeout0F
'he function monitors 3sets3 of file descriptorsF in particular readfds+ writefds+ and
exceptfds. If "ou want to see if "ou can read from standard input and some soc%et
descriptor+ soc%fd+ Bust add the file descriptors 7 and soc%fd to the set readfds. 'he
parameter numfds should 2e set to the !alues of the highest file descriptor plus one. In
this example+ it should 2e set to soc%fdY:+ since it is assuredl" higher than standard
input /70.
$hen select/0 returns+ readfds will 2e modified to reflect which of the file descriptors
"ou selected is read" for reading. 9ou can test them with the macro 1.GI((A'/0+ 2elow.
>efore progressing much further+ I'll tal% a2out how to manipulate these sets. Aach
set is of the t"pe fdGset. 'he following macros operate on this t"pe#
1.GVA8@/fdGset Jset0 ) clears a file descriptor set
1.G(A'/int fd+ fdGset Jset0 ) adds fd to the set
1.GCL8/int fd+ fdGset Jset0 ) remo!es fd from the set
1.GI((A'/int fd+ fdGset Jset0 ) tests to see if fd is in the set
=6
1inall"+ what is this weirded out struct time!al& $ell+ sometimes "ou don't want to wait
fore!er for someone to send "ou some data. Ma"2e e!er" 6O seconds "ou want to
print 3(till Going...3 to the terminal e!en though nothing has happened. 'his time
structure allows "ou to specif" a timeout period. If the time is exceeded and select/0
still hasn't found an" read" file descriptors+ it'll return so "ou can continue
processing.
'he struct time!al has the follow fields#
struct time!al I
int t!GsecF ?J seconds J?
int t!GusecF ?J microseconds J?
MF
Hust set t!Gsec to the num2er of seconds to wait+ and set t!Gusec to the num2er of
microseconds to wait. 9es+ that's microseconds+ not milliseconds. 'here are :+777
microseconds in a millisecond+ and :+777 milliseconds in a second. 'hus+ there are
:+777+777 microseconds in a second. $h" is it 3usec3& 'he 3u3 is supposed to loo%
li%e the Gree% letter Mu that we use for 3micro3. -lso+ when the function returns+
timeout might 2e updated to show the time still remaining. 'his depends on what
fla!or of Unix "ou're running.
9a", $e ha!e a microsecond resolution timer, $ell+ don't count on it. (tandard Unix
timeslice is :77 milliseconds+ so "ou'll pro2a2l" ha!e to wait at least that long+ no
matter how small "ou set "our struct time!al.
@ther things of interest# If "ou set the fields in "our struct time!al to 7+ select/0 will
timeout immediatel"+ effecti!el" polling all the file descriptors in "our sets. If "ou
set the parameter timeout to ULL+ it will ne!er timeout+ and will wait until the first
file descriptor is read". 1inall"+ if "ou don't care a2out waiting for a certain set+ "ou
can Bust set it to ULL in the call to select/0.
'he following code snippet waits =.E seconds for something to appear on standard input#
Ninclude Ps"s?time.hT
Ninclude Ps"s?t"pes.hT
Ninclude Punistd.hT
Ndefine ('.I 7 ?J file descriptor for standard input J?
main/0
I
struct time!al t!F
fdGset readfdsF
47
t!.t!Gsec Q =F
t!.t!Gusec Q E77777F
1.GVA8@/Ureadfds0F
1.G(A'/('.I+ Ureadfds0F
?J don't care a2out writefds and exceptfds# J?
select/('.IY:+ Ureadfds+ ULL+ ULL+ Ut!0F
if /1.GI((A'/('.I+ Ureadfds00
printf/3- %e" was pressed,Sn30F
else
printf/3'imed out.Sn30F
M
If "ou're on a line 2uffered terminal+ the %e" "ou hit should 2e 8A'U8 or it will
time out an"wa".
ow+ some of "ou might thin% this is a great wa" to wait for data on a datagram
soc%et))and "ou are right# it might 2e. (ome Unices can use select in this manner+
and some can't. 9ou should see what "our local man page sa"s on the matter if "ou
want to attempt it.
@ne final note of interest a2out select/0# if "ou ha!e a soc%et that is listen/0'ing+ "ou can
chec% to see if there is a new connection 2" putting that soc%et's file descriptor in the
readfds set.
9ou'!e come this far+ and now "ou're screaming for more, $here else can "ou go to
learn more a2out all this stuff&
'r" the following man pages+ for starters#
soc%et/0
2ind/0
connect/0
listen/0
accept/0
send/0
rec!/0
sendto/0
rec!from/0
4:
close/0
shutdown/0
getpeername/0
getsoc%name/0
gethost2"name/0
gethost2"addr/0
getproto2"name/0
fcntl/0
select/0
perror/0
4=

Das könnte Ihnen auch gefallen