0% found this document useful (0 votes)
39 views35 pages

Socket Programming: 15 - 441 Computer Networks, Spring 2010 Your Tas

This document provides an overview of socket programming in C. It discusses the motivation for using sockets, identifies key steps in socket programming including setting up sockets, binding, listening, accepting connections (for servers), and connecting (for clients). It also covers important socket-related concepts like addressing, multiplexing, DNS, and byte ordering functions. The overall process for a basic TCP server is outlined with code examples, including setting up the socket, binding, listening, and accepting connections. The client connection process is also summarized.

Uploaded by

leela sravani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views35 pages

Socket Programming: 15 - 441 Computer Networks, Spring 2010 Your Tas

This document provides an overview of socket programming in C. It discusses the motivation for using sockets, identifies key steps in socket programming including setting up sockets, binding, listening, accepting connections (for servers), and connecting (for clients). It also covers important socket-related concepts like addressing, multiplexing, DNS, and byte ordering functions. The overall process for a basic TCP server is outlined with code examples, including setting up the socket, binding, listening, and accepting connections. The client connection process is also summarized.

Uploaded by

leela sravani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

Socket

 Programming  
15-­‐441  Computer  Networks,  Spring  2010  
Your  TAs  
Lecture  Today  
•  MoCvaCon  for  sockets  
•  What’s  in  a  socket?  
•  Working  with  socket  
•  Concurrent  network  applicaCons  
•  Project  1  
Why  Socket?  
•  How  can  I  program  a  network  applicaCon?  
–  Share  data  
–  Send  messages  
–  Finish  course  projects...  

•  IPC  -­‐  Interprocess  CommunicaCon  


IdenCfy  the  DesCnaCon  
•  Addressing  
– IP  address  
– hostname  (resolve  to  IP  address  via  DNS)  
•  MulCplexing  
– port   Server socket address
208.216.181.15:80
Client socket address
128.2.194.242:3479 FTP Server
(port 21)‫‏‬

Client HTTP Server


Connection socket pair (port 80)‫‏‬
‫)‏‬208.216.181.15:80 ,128.2.194.242:3479(

Client host address Server host address


128.2.194.242 208.216.181.15
Sockets  
•  How  to  use  sockets  
– Setup  socket  
•  Where  is  the  remote  machine  (IP  address,  hostname)  
•  What  service  gets  the  data  (port)  
– Send  and  Receive  
•  Designed  just  like  any  other  I/O  in  unix  
•  send  -­‐-­‐  write  
•  recv  -­‐-­‐  read  
– Close  the  socket  
Overview  
Client Server

socket socket

bind open_listenfd
open_clientfd
listen
Connection
request
connect accept

write read
Client /
Server
Session read write

EOF
close read

close
Step  1  –  Setup  Socket  
•  Both  client  and  server  need  to  setup  the  socket    
– int  socket(int  domain,  int  type,  int  protocol);  
•  domain  
– AF_INET  -­‐-­‐  IPv4  (AF_INET6  for  IPv6)  
•  type  
– SOCK_STREAM  -­‐-­‐  TCP  
– SOCK_DGRAM  -­‐-­‐  UDP  
•  protocol  
– 0  
•  For  example,  
– int  sockfd  =  socket(AF_INET,  SOCK_STREAM,  0);  
Step  2  (Server)  -­‐  Binding    
•  Only  server  need  to  bind  
– int  bind(int  sockfd,  const  struct  sockaddr  *my_addr,  
socklen_t  addrlen);  
•  sockfd  
– file  descriptor  socket()  returned  
•  my_addr  
– struct  sockaddr_in  for  IPv4  
– cast  (struct  sockaddr_in*)  to  (struct  sockaddr*)  
struct sockaddr_in {
short sin_family; // e.g. AF_INET
unsigned short sin_port; // e.g. htons(3490)‫‏‬
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
struct in_addr {
unsigned long s_addr; // load with inet_aton()‫‏‬
};
What  is  that  Cast?  
•  bind()  takes  in  protocol-­‐independent  (struct  
sockaddr*)  
struct sockaddr {
unsigned short sa_family; // address family
char sa_data[14]; // protocol address
};

– C’s  polymorphism  
– There  are  structs  for  IPv6,  etc.  
Step  2  (Server)  -­‐  Binding  contd.  
•  addrlen  
– size  of  the  sockaddr_in    
struct sockaddr_in saddr;
int sockfd;
unsigned short port = 80;

if((sockfd=socket(AF_INET, SOCK_STREAM, 0) < 0) { // from back a couple slides


printf(“Error creating socket\n”);
...
}

memset(&saddr, '\0', sizeof(saddr)); // zero structure out


saddr.sin_family = AF_INET; // match the socket() call
saddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind to any local address
saddr.sin_port = htons(port); // specify port to listen on

if((bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { // bind!


printf(“Error binding\n”);
...
}
What  is  htonl(),  htons()?  
•  Byte  ordering  
– Network  order  is  big-­‐endian  
– Host  order  can  be  big-­‐  or  lidle-­‐endian  
•  x86  is  lidle-­‐endian  
•  SPARC  is  big-­‐endian  
•  Conversion  
– htons(),  htonl():  host  to  network  short/long  
– ntohs(),  ntohl():  network  order  to  host  short/long  
•  What  need  to  be  converted?  
– Addresses  
– Port  
– etc.  
Step  3  (Server)  -­‐  Listen  
•  Now  we  can  listen  
– int  listen(int  sockfd,  int  backlog);  
•  sockfd  
– again,  file  descriptor  socket()  returned  
•  backlog  
– number  of  pending  connecCons  to  queue  
•  For  example,  
– listen(sockfd,  5);  
Step  4  (Server)  -­‐  Accept  
•  Server  must  explicitly  accept  incoming  connec<ons  
–  int  accept(int  sockfd,  struct  sockaddr  *addr,  socklen_t  *addrlen)  
•  sockfd  
–  again...  file  descriptor  socket()  returned  
•  addr  
–  pointer  to  store  client  address,  (struct  sockaddr_in  *)  cast  to  
(struct  sockaddr  *)  
•  addrlen  
–  pointer  to  store  the  returned  size  of  addr,  should  be  sizeof
(*addr)  
•  For  example  
–  int  isock=accept(sockfd,  (struct  sockaddr_in  *)  &caddr,  &clen);  
Put  Server  Together  
struct sockaddr_in saddr, caddr;
int sockfd, clen, isock;
unsigned short port = 80;

if((sockfd=socket(AF_INET, SOCK_STREAM, 0) < 0) { // from back a couple slides


printf(“Error creating socket\n”);
...
}

memset(&saddr, '\0', sizeof(saddr)); // zero structure out


saddr.sin_family = AF_INET; // match the socket() call
saddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind to any local address
saddr.sin_port = htons(port); // specify port to listen on

if((bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { // bind!


printf(“Error binding\n”);
...
}

if(listen(sockfd, 5) < 0) { // listen for incoming connections


printf(“Error listening\n”);
...
}

clen=sizeof(caddr)‫‏‬
if((isock=accept(sockfd, (struct sockaddr *) &caddr, &clen)) < 0) { // accept one
printf(“Error accepting\n”);
...
}
What  about  client?  
•  Client  need  not  bind,  listen,  and  accept  
•  All  client  need  to  do  is  to  connect  
– int  connect(int  sockfd,  const  struct  sockaddr  
*saddr,  socklen_t  addrlen);  
•  For  example,  
– connect(sockfd,  (struct  sockaddr  *)  &saddr,  sizeof
(saddr));  
Domain  Name  System  (DNS)  
•  What  if  I  want  to  send  data  to  “www.slashdot.org”?  
–  DNS:  Conceptually,  DNS  is  a  database  collecCon  of  host  entries  
struct hostent {
char *h_name; // official hostname
char **h_aliases; // vector of alternative hostnames
int h_addrtype; // address type, e.g. AF_INET
int h_length; // length of address in bytes, e.g. 4 for IPv4
char **h_addr_list; // vector of addresses
char *h_addr; // first host address, synonym for h_addr_list[0]
};

•  hostname  -­‐>  IP  address  


–  struct  hostent  *gethostbyname(const  char  *name);  

•  IP  address  -­‐>  hostname  


–  struct  hostent  *gethostbyaddr(const  char  *addr,  int  len,  int  
type);  
Put  Client  Together  
struct sockaddr_in saddr;
struct hostent *h;
int sockfd, connfd;
unsigned short port = 80;

if((sockfd=socket(AF_INET, SOCK_STREAM, 0) < 0) { // from back a couple slides


printf(“Error creating socket\n”);
...
}

if((h=gethostbyname(“www.slashdot.org”)) == NULL) { // Lookup the hostname


printf(“Unknown host\n”);
...
}

memset(&saddr, '\0', sizeof(saddr)); // zero structure out


saddr.sin_family = AF_INET; // match the socket() call
memcpy((char *) &saddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length); // copy the address
saddr.sin_port = htons(port); // specify port to connect to

if((connfd=connect(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { // connect!


printf(“Cannot connect\n”);
...
}
We  Are  Connected  
•  Server  accepCng  connecCons  and  client  
connecCng  to  servers  
•  Send  and  receive  data  
– ssize_t  read(int  fd,  void  *buf,  size_t  len);  
– ssize_t  write(int  fd,  const  void  *buf,  size_t  len);  
•  For  example,  
– read(sockfd,  buffer,  sizeof(buffer));  
– write(sockfd,  “hey\n”,  strlen(“hey\n”));  
TCP  Framing  
•  TCP  does  NOT  guarantee  message  boundaries  
– IRC  commands  are  terminated  by  a  newline  
– But  you  may  not  get  one  at  the  end  of  read(),  e.g.  
•  One  Send  “Hello\n”  
•  MulCple  Receives  “He”,  “llo\n”  
– If  you  don’t  get  the  enCre  line  from  one  read(),  
use  a  buffer  
Revisited  
Client Server

socket socket

bind open_listenfd
open_clientfd
listen
Connection
request
connect accept

write read
Client /
Server
Session read write

EOF
close read

close
Close  the  Socket  
•  Don’t  forget  to  close  the  socket  descriptor,  like  
a  file  
– int  close(int  sockfd);  

•  Now  server  can  loop  around  and  accept  a  new  


connecCon  when  the  old  one  finishes  
•  What’s  wrong  here?  
Server  Flaw  
client 1 server client 2
call accept
call connect
ret connect
ret accept
call fgets
Server blocks call read call connect
User goes waiting for
out to lunch data from
Client 2 blocks
Client 1
waiting to complete
Client 1 blocks its connection
waiting for user request until after
to type in data lunch!

Taken from D. Murray, R. Bryant, and G. Langale 15-441/213 slides


Concurrent  Servers  
client 1 server client 2
call accept call connect
call connect
ret connect
ret accept
call fgets call read (don’t block)‫‏‬

call accept
User goes ret connect
out to lunch ret accept call fgets

write
Client 1
blocks call read call read
waiting for
user to type write
in data
end read
close
close

Taken from D. Murray, R. Bryant, and G. Langale 15-441/213 slides


Concurrency  
•  Threading  
– Easier  to  understand  
– Race  condiCons  increase  complexity  
•  Select()  
– Explicit  control  flows,  no  race  condiCons  
– Explicit  control  more  complicated  
•  There  is  no  clear  winner,  but  you  MUST  use  
select()…  
What  is  select()?  
•  Monitor  mulCple  descriptors  
•  How  does  it  work?  
– Setup  sets  of  sockets  to  monitor  
– select():  blocking  unCl  something  happens  
– “Something”  could  be  
•  Incoming  connecCon:  accept()  
•  Clients  sending  data:  read()  
•  Pending  data  to  send:  write()  
•  Timeout  
Concurrency  –  Step  1  
•  Allowing  address  reuse  
int sock, opts=1;

sock = socket(...); // To give you an idea of where the new code goes

setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts));

•  Then  we  set  the  sockets  to  be  non-­‐blocking  


if((opts = fcntl(sock, F_GETFL)) < 0) { // Get current options
printf(“Error...\n”);
...
}
opts = (opts | O_NONBLOCK); // Don't clobber your old settings
if(fcntl(sock, F_SETFL, opts) < 0) {
printf(“Error...\n”);
...
}

bind(...); // To again give you an idea where the new code goes
Concurrency  –  Step  2  
•  Monitor  sockets  with  select()  
– int  select(int  maxfd,  fd_set  *readfds,  fd_set  *writefds,  
fd_set  *excepUds,  const  struct  Vmespec  *Vmeout);  
•  maxfd  
– max  file  descriptor  +  1  
•  fd_set:  bit  vector  with  FD_SETSIZE  bits  
– readfds:  bit  vector  of  read  descriptors  to  monitor  
– writefds:  bit  vector  of  write  descriptors  to  monitor  
– excepUds:  set  to  NULL  
•  Vmeout  
– how  long  to  wait  without  acCvity  before  returning  
What  about  bit  vectors?  
•  void  FD_ZERO(fd_set  *fdset);  
– clear  out  all  bits  
•  void  FD_SET(int  fd,  fd_set  *fdset);    
– set  one  bit  
•  void  FD_CLR(int  fd,  fd_set  *fdset);    
– clear  one  bit  
•  int  FD_ISSET(int  fd,  fd_set  *fdset);    
– test  whether  fd  bit  is  set  
The  Server  
// socket() call and non-blocking code is above this point

if((bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { // bind!


printf(“Error binding\n”);
...
}

if(listen(sockfd, 5) < 0) { // listen for incoming connections


printf(“Error listening\n”);
...
}

clen=sizeof(caddr);

// Setup pool.read_set with an FD_ZERO() and FD_SET() for


// your server socket file descriptor. (whatever socket() returned)‫‏‬

while(1) {
pool.ready_set = pool.read_set; // Save the current state
pool.nready = select(pool.maxfd+1, &pool.ready_set, &pool.write_set, NULL, NULL);

if(FD_ISSET(sockfd, &pool.ready_set)) { // Check if there is an incoming conn


isock=accept(sockfd, (struct sockaddr *) &caddr, &clen); // accept it
add_client(isock, &pool); // add the client by the incoming socket fd
}

check_clients(&pool); // check if any data needs to be sent/received from clients


}

...

close(sockfd);
What  is  pool?  
typedef struct { /* represents a pool of connected descriptors */
int maxfd; /* largest descriptor in read_set */
fd_set read_set; /* set of all active read descriptors */
fd_set write_set; /* set of all active read descriptors */
fd_set ready_set; /* subset of descriptors ready for reading */
int nready; /* number of ready descriptors from select */
int maxi; /* highwater index into client array */
int clientfd[FD_SETSIZE]; /* set of active descriptors */
rio_t clientrio[FD_SETSIZE]; /* set of active read buffers */
... // ADD WHAT WOULD BE HELPFUL FOR PROJECT1
} pool;
What  about  checking  clients?  
•  The  main  loop  only  tests  for  incoming  
connecCons  
– There  are  other  reasons  the  server  wakes  up  
– Clients  are  sending  data,  pending  data  to  write  to  
buffer,  clients  closing  connecCons,  etc.  
•  Store  all  client  file  descriptors  
– in  pool  
•  Keep  the  while(1)  loop  thin  
– Delegate  to  funcCons  
•  Come  up  with  your  own  design  
Summary  
•  Sockets  
–  socket  setup  
–  I/O  
–  close  
•  Client:    socket()-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐>connect()-­‐>I/O-­‐>close()  
•  Server:  socket()-­‐>bind()-­‐>listen()-­‐>accept()-­‐-­‐-­‐>I/O-­‐>close()  

•  DNS  
–  gethostbyname()  
•  Concurrency  
–  select()  
•  Bit  vector  operaCons  
–  fd_set,  FD_ZERO(),  FD_SET(),  FD_CLR(),  FD_ISSET()  
About  Project  1  
•  Standalone  IRC  server  
– Checkpoint  1:  subversion  and  Makefile  
•  Check  in  a  Makefile  and  source  code  
•  Makefile  can  build  executable  named  sircd  
•  No  server  funcCons  necessary  
– Checkpoint  2:  echo  server  
•  Use  select()  to  handle  mulCple  clients  
SuggesCons  
•  Start  early!  
– Work  ahead  of  checkpoints  
•  Read  the  man  pages  
•  Email  Kaushik  (kaushik  AT  cs  DOT  cmu  DOT  
edu)  if  you  didn’t  get  a  svn  username  and  
password  
Reference  for  Socket  Programming  
•  hdp://www.lowtek.com/sockets/  

•  Feel  free  to  share  your  reference  on  the  


bboard!  

You might also like