Sockets Programming in UNIX

Download Report

Transcript Sockets Programming in UNIX

Sockets Programming in UNIX

References: Internetworking with TCP/IP Vol III - BSD version UNIX Network Programming - W. Richard Stevens CSTP FS97 CS490D (cotter) 1

Sockets Programming in UNIX

• UNIX Socket API functions • Example TCP / UDP Clients • Example TCP / UDP Servers CSTP WS01 CS423 (cotter) 2

Basic Socket Functions Server(UNIX)

• Create a socket of a particular type – retcode = socket (family, type, protocol ) – s = socket (PF_INET, SOCK_STREAM, 0) – returns socket number or -1 on error • Bind that socket to a specific port – retcode = bind (socket, localaddr, addrlen ) – n = bind (s, (struct sockaddr *)myaddr, sizeof(myaddr)) – returns 0 on success, -1 on fail CSTP WS01 CS423 (cotter) 3

Basic Socket Functions Server(UNIX)

• Wait for an incoming message – retcode = listen (socket, queuelen) – ans = listen(s, 0) /* queuelen max ~ 5*/ – return value 0 = success, -1 = fail • Create a new socket and return new socket ID to client – retcode = accept (socket, addr, addrlen) – ans = accept (s, (struct sockaddr *)cl_addr, sizeof(cl_addr)) – return value socket number = success, -1 = fail CSTP WS01 CS423 (cotter) 4

Basic Socket Functions Server (UNIX)

• Read / send a message – retcode = read [write] (socket, buff, bufflen) – ans = read (s, buf, sizeof(buf)) – ans = write (s, buf, sizeof(buf)) – return value word count = success, -1 = fail • Close the socket – retcode = shutdown (socket , direction) • direction: 0 means input, 1 means output, 2 means both – retcode = close (socket ) – return value 0 = success, -1 = fail CSTP WS01 CS423 (cotter) 5

Basic Socket Functions Client (UNIX)

• Create a socket of a particular type – Socket ( ) • Establish a connection to a remote Port/Socket – retcode = connect (socket, addr, addrlen) – ans = connect (s, (struct sockaddr *)&svr, sizeof(svr)) – return value 0 = success, -1 = fail • Send and receive messages to/from remote socket – Read ( ) / Write ( ) • Close the socket – Close ( ) CSTP WS01 CS423 (cotter) 6

Additional Socket Functions (UNIX)

• Byte ordering functions – servaddr.sin_port = htons (SERV_PORT) – myaddr.sin_addr.s_addr = htonl (INADDR_ANY) • Name resolution functions – host / protocol / service, by name / address / port • Other Stuff – zero out memory blocks • bzero ((char *)&myaddr, sizeof(myaddr)); – copy memory blocks • bcopy (hp->h_addr, (caddr_T)&svaddr.sin_addr, hp->h_length) CSTP WS01 CS423 (cotter) 7

Example UNIX Client

• Develop a set of procedures that can be used by other programs to implement client / server.

int connectTCP (host, service) int connectsock(host, service, “tcp”) [identify service, host, port] [get a socket] [connect to service / host / port] [return socket number] CSTP WS01 CS423 (cotter) 8

int

Example UNIX Client connectTCP.c

connectTCP (char *host, char *service) { return connectsock (host, service, “tcp”); } CSTP WS01 CS423 (cotter) 9

Example UNIX Client connectsock.c

#include , , , int connectsock (char *host, char *service, char *protocol) { struct hostent struct servent struct protoent *phe; *pse; *ppe; struct sockaddr_in sin; int s, type; CSTP WS01 CS423 (cotter) 10

Example UNIX Client connectsock.c

bzero ((char *)&sin, sizeof (sin)); sin.sin_family = AF_INET; if (pse = getservbyname (service, protocol) ) sin.sin_port = pse ->s_port; else if ( (sin.sin_port = htons((u_short)atoi(service))) == 0) error_exit (“can’t get %s service\n”, service); if (phe = gethostbyname (host) ) bcopy(phe->h_addr, (char *)&sin.sin_addr, phe->h_length); else if ((sin.sin_addr.s_addr = inet_addr(host)) ==

INADDR_NONE

) error_exit (“can’t get %s host\n”, host); CSTP WS01 CS423 (cotter) 11

Example UNIX Client connectsock.c

if ( (ppe = getprotobyname (protocol) == 0) error_exit (“can’t get %s host\n”, host); if (strcmp (protocol, “tcp”) == 0) type = SOCK_STREAM; else type = SOCK_DGRAM; if (s = socket (PF_INET, type, ppe->p_proto)) < 0) error_exit (“Can’t create a socket\n”); if (connect (s, (struct sockaddr *)&sin, sizeof(sin)) < 0) error_exit (“can’t connect to remote socket\n”); return s; } CSTP WS01 CS423 (cotter) 12

Example UNIX Client TCPecho.c

#include #define LINELEN int main (argc, argv) { 128 host = argv[1]; service = argv[2]; TCPecho (host, service); exit (0); } CSTP WS01 CS423 (cotter) 13

Example UNIX Client TCPecho.c

int TCPecho (char *host, char *service) { char buf[LINELEN+1]; int s, n, outchars, inchars; s = connectTCP (host, service); while (fgets (buf, sizeof(buf), stdin)) { buf[LINELEN] = ‘\0’; outchars = strlen(buf); (void) write (s, buf, outchars); CSTP WS01 CS423 (cotter) 14

}

Example UNIX Client TCPecho.c

for (inchars = 0; inchars < outchars; inchars +=n) { n = read (s, &buf[inchars], outchars - inchars); if (n < 0) error_exit(“socket read failed\n”); } fputs (buf, stdout); } CSTP WS01 CS423 (cotter) 15

TCP Client Algorithm

• Client / Server Communications – request / response interaction – write / read (send / recv) • Single write may require multiple reads – response may be segmented – continue appending reads until return length = 0 CSTP WS01 CS423 (cotter) 16

Example UNIX Client UDPecho.c

#include #define LINELEN int main (argc, argv) { 128 host = argv[1]; service = argv[2]; UDPecho (host, service); exit (0); } CSTP WS01 CS423 (cotter) 17

Example UNIX Client UDPecho.c

int UDPecho (char *host, char *service) { char buf[LINELEN+1]; int s, n, outchars, inchars; s = connectUDP (host, service); while (fgets (buf, sizeof(buf), stdin)) { buf[LINELEN] = ‘\0’; outchars = strlen(buf); (void) write (s, buf, outchars); CSTP WS01 CS423 (cotter) 18

}

Example UNIX Client UDPecho.c

if (read (s, buf, nchars) < 0) error_exit (“Socket read failed \n”); fputs (buf, stdout); } CSTP WS01 CS423 (cotter) 19

Iterative Connectionless Servers TIME Server

/* UDPtimed.c - main */ #include #include #include #include #include #include extern int errno; int int passiveUDP(const char *service); errexit(const char *format, ...); #define UNIXEPOCH CSTP WS01 2208988800 /* UNIX epoch, in UCT secs*/ CS423 (cotter) 20

Iterative Connectionless Servers

{

TIME Server

int main(int argc, char *argv[]) struct sockaddr_in fsin; /* the from address of a client */ char *service = "time"; /* service name or port number */ char buf[1]; int sock; time_t int alen; now; /* "input" buffer; any size > 0 */ /* server socket /* current time /* from-address length */ */ */ switch (argc) { case 1: break; case 2: default: } service = argv[1]; break; errexit("usage: UDPtimed [port]\n"); CSTP WS01 CS423 (cotter) 21

Iterative Connectionless Servers TIME Server

sock = passiveUDP(service); } while (1) { alen = sizeof(fsin); if (recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen) < 0) errexit("recvfrom: %s\n", strerror(errno)); (void) time(&now); now = htonl((u_long)(now + UNIXEPOCH)); (void) sendto(sock, (char *)&now, sizeof(now), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } CSTP WS01 CS423 (cotter) 22

Concurrent Connection-Oriented TCPechod.c

#include ,,, ,,,, ,,,, #define QLEN 5 #define BUFSIZE /* maximum connection queue length */ 4096 extern int void errno; reaper(int); int int int TCPechod(int fd); errexit(const char *format, ...); passiveTCP(const char *service, int qlen); CSTP WS01 CS423 (cotter) 23

Concurrent Connection-Oriented TCPechod.c

int main(int argc, char *argv[ ])

{ char *service = "echo"; /* service name or port number*/ struct sockaddr_in fsin; /* the address of a client */ int alen; int msock; int ssock; switch (argc) { /* length of client's address*/ /* master server socket */ /* slave server socket */ case 1: case 2: default: } break; service = argv[1]; break; errexit("usage: TCPechod [port]\n"); CSTP WS01 CS423 (cotter) 24

Concurrent Connection-Oriented TCPechod.c

msock = passiveTCP(service, QLEN); (void) signal(SIGCHLD, reaper); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) { if (errno == EINTR) continue; errexit("accept: %s\n", strerror(errno)); } CSTP WS01 CS423 (cotter) 25

}

Concurrent Connection-Oriented TCPechod.c

switch (fork()) { case 0: /* child */ (void) close(msock); exit(TCPechod(ssock)); default: /* parent */ (void) close(ssock); break; case -1: errexit("fork: %s\n", strerror(errno)); } } CSTP WS01 CS423 (cotter) 26

Concurrent Connection-Oriented TCPechod.c

int

{

TCPechod(int fd)

char buf[BUFSIZ]; int cc; while (cc = read(fd, buf, sizeof buf)) { if (cc < 0) errexit("echo read: %s\n", strerror(errno)); if (write(fd, buf, cc) < 0) errexit("echo write: %s\n", strerror(errno)); } return 0; } CSTP WS01 CS423 (cotter) 27

Concurrent Connection-Oriented TCPechod.c

/*-------------------------------------------------- * reaper - clean up zombie children *--------------------------------------------------*/ /*ARGSUSED*/

void reaper(int sig)

{ int status; } while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0) /* empty */; CSTP WS01 CS423 (cotter) 28