sockets programming in unix
DESCRIPTION
Sockets Programming in UNIX. References: Internetworking with TCP/IP Vol III - BSD version UNIX Network Programming - W. Richard Stevens. Sockets Programming in UNIX. UNIX Socket API functions Example TCP / UDP Clients Example TCP / UDP Servers. Basic Socket Functions Server(UNIX). - PowerPoint PPT PresentationTRANSCRIPT
CSTP FS97 CS490D (cotter) 1
Sockets Programming in UNIX
References:
Internetworking with TCP/IP Vol III - BSD version
UNIX Network Programming - W. Richard Stevens
CSTP WS01 CS423 (cotter) 2
Sockets Programming in UNIX
• UNIX Socket API functions• Example TCP / UDP Clients• Example TCP / UDP Servers
CSTP WS01 CS423 (cotter) 3
Basic Socket FunctionsServer(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) 4
Basic Socket FunctionsServer(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) 5
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) 6
Basic Socket FunctionsClient (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) 7
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) 8
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) 9
Example UNIX ClientconnectTCP.c
int connectTCP (char *host, char *service)
{
return connectsock (host, service, “tcp”);
}
CSTP WS01 CS423 (cotter) 10
Example UNIX Clientconnectsock.c
#include <sys/types.h>, <sys/socket.h>, <netinet/in.h>,<netdb.h>
int connectsock (char *host, char *service, char *protocol)
{
struct hostent *phe;
struct servent *pse;
struct protoent *ppe;
struct sockaddr_in sin;
int s, type;
CSTP WS01 CS423 (cotter) 11
Example UNIX Clientconnectsock.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) 12
Example UNIX Clientconnectsock.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) 13
Example UNIX ClientTCPecho.c
#include <stdio.h>
#define LINELEN 128
int main (argc, argv)
{
host = argv[1];
service = argv[2];
TCPecho (host, service);
exit (0);
}
CSTP WS01 CS423 (cotter) 14
Example UNIX ClientTCPecho.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) 15
Example UNIX ClientTCPecho.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) 16
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) 17
Example UNIX ClientUDPecho.c
#include <stdio.h>
#define LINELEN 128
int main (argc, argv)
{
host = argv[1];
service = argv[2];
UDPecho (host, service);
exit (0);
}
CSTP WS01 CS423 (cotter) 18
Example UNIX ClientUDPecho.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) 19
Example UNIX ClientUDPecho.c
if (read (s, buf, nchars) < 0)
error_exit (“Socket read failed \n”);
fputs (buf, stdout);
}
}
CSTP WS01 CS423 (cotter) 20
Iterative Connectionless ServersTIME Server
/* UDPtimed.c - main */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
extern int errno;
int passiveUDP(const char *service);
int errexit(const char *format, ...);
#define UNIXEPOCH 2208988800 /* UNIX epoch, in UCT secs*/
CSTP WS01 CS423 (cotter) 21
Iterative Connectionless ServersTIME 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]; /* "input" buffer; any size > 0 */
int sock; /* server socket */
time_t now; /* current time */
int alen; /* from-address length */
switch (argc) {
case 1: break;
case 2: service = argv[1];
break;
default: errexit("usage: UDPtimed [port]\n");
}
CSTP WS01 CS423 (cotter) 22
Iterative Connectionless ServersTIME 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) 23
Concurrent Connection-OrientedTCPechod.c
#include <sys/types.h>,<sys/signal.h>,<sys/socket.h>, <sys/time.h>,<sys/wait.h>,<sys/resource.h>,<sys/errno.h>, <netinet/in.h>,<unistd.h>,<stdlib.h>,<stdio.h>,<string.h>
#define QLEN 5 /* maximum connection queue length */
#define BUFSIZE 4096
extern int errno;
void reaper(int);
int TCPechod(int fd);
int errexit(const char *format, ...);
int passiveTCP(const char *service, int qlen);
CSTP WS01 CS423 (cotter) 24
Concurrent Connection-OrientedTCPechod.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; /* length of client's address*/
int msock; /* master server socket */
int ssock; /* slave server socket */
switch (argc) {
case 1: break;
case 2: service = argv[1];
break;
default: errexit("usage: TCPechod [port]\n");
}
CSTP WS01 CS423 (cotter) 25
Concurrent Connection-OrientedTCPechod.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) 26
Concurrent Connection-OrientedTCPechod.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) 27
Concurrent Connection-OrientedTCPechod.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) 28
Concurrent Connection-OrientedTCPechod.c
/*---------------------------------------------------
* reaper - clean up zombie children
*--------------------------------------------------*/
/*ARGSUSED*/
void
reaper(int sig)
{
int status;
while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0)
/* empty */;
}