28
1 Sockets Programming in Linux References: Internetworking with TCP/IP Vol III - Linux version UNIX Network Programming - W. Richard Stevens

Sockets Programming in Linux

Embed Size (px)

DESCRIPTION

Sockets Programming in Linux. References: Internetworking with TCP/IP Vol III - Linux version UNIX Network Programming - W. Richard Stevens. Sockets Programming in Linux. Linux / UNIX Socket API functions Example TCP / UDP Clients Example TCP / UDP Servers. - PowerPoint PPT Presentation

Citation preview

Page 1: Sockets Programming in Linux

1

Sockets Programming in Linux

References:

Internetworking with TCP/IP Vol III - Linux version

UNIX Network Programming - W. Richard Stevens

Page 2: Sockets Programming in Linux

2

Sockets Programming in Linux

• Linux / UNIX Socket API functions

• Example TCP / UDP Clients

• Example TCP / UDP Servers

Page 3: Sockets Programming in Linux

3

Basic Socket FunctionsServer(Linux / 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

Page 4: Sockets Programming in Linux

4

Basic Socket FunctionsServer(Linux / 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

Page 5: Sockets Programming in Linux

5

Basic Socket Functions Server (Linux / UNIX)

• Read / send a message– retcode = read [write] (socket, buff, bufflen)– ans = read (s, buf, sizeof(buf));– ans = write (s, buf, strlen(buf));– return value word count = success, -1 = fail– retcode = recv [send] (socket, buff, bufflen, 0)– ans = recv (s, buf, sizeof(buf), 0);– ans = send (s, buf, strlen(buf), 0);– 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

Page 6: Sockets Programming in Linux

6

Basic Socket FunctionsClient (Linux / 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( ) of recv( ) / send(

• Close the socket– Close ( )

Page 7: Sockets Programming in Linux

7

Additional Socket Functions(Linux / 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)

Page 8: Sockets Programming in Linux

8

Example Linux 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]

Page 9: Sockets Programming in Linux

9

Linux Client - Connectsock.c

int connectTCP (char *host, char *service)

{

return connectsock (host, service, “tcp”);

}

Page 10: Sockets Programming in Linux

10

Linux Client - Connectsock.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;

Page 11: Sockets Programming in Linux

11

Linux 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);

Page 12: Sockets Programming in Linux

12

Linux 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;}

Page 13: Sockets Programming in Linux

13

Example Linux Client - TCPecho.c

#include <stdio.h>

#define LINELEN 128

int main (argc, argv)

{

host = argv[1];

service = argv[2];

TCPecho (host, service);

exit (0);

}

Page 14: Sockets Programming in Linux

14

Example Linux 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);

Page 15: Sockets Programming in Linux

15

Example Linux 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);}

}

Page 16: Sockets Programming in Linux

16

TCP Client Algorithm Issues

• 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

Page 17: Sockets Programming in Linux

17

Example Linux Client - UDPecho.c

#include <stdio.h>

#define LINELEN 128

int main (argc, argv)

{

host = argv[1];

service = argv[2];

UDPecho (host, service);

exit (0);

}

Page 18: Sockets Programming in Linux

18

Example Linux 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);

Page 19: Sockets Programming in Linux

19

Example Linux Client - UDPecho.c

if (read (s, buf, nchars) < 0)

error_exit (“Socket read failed \n”);

fputs (buf, stdout);

}

}

Page 20: Sockets Programming in Linux

20

Iterative Connectionless ServerTIME 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 secs*/

Page 21: Sockets Programming in Linux

21

Iterative Connectionless ServerTIME Server

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

struct sockaddr_in fsin; /* the 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");

}

Page 22: Sockets Programming in Linux

22

Iterative Connectionless ServerTIME 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));

}

}

Page 23: Sockets Programming in Linux

23

Concurrent Connection-OrientedTCPechod.c

#include <sys/types.h, <sys/signal.h, <sys/socket.h, <sys/time.h, <sys/resource.h, <sys/wait.h, <sys/errno.h, <netinet/in.h>, <pthread.h>, <unistd.h>, <stdlib.h>, <stdio.h>, <string.h>, <errno.h>

#define QLEN 10 /* max connect queue length*/

#define BUFSIZE 4096

extern int errno;

void * TCPechod(void *pfd);

int errexit(const char *format, ...);

int passiveTCP(const char *service, int qlen);

Page 24: Sockets Programming in Linux

24

Concurrent Connection-OrientedTCPechod.c

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

char *service = "echo"; /* service name/port #*/

struct sockaddr_in fsin; /* address of client*/

unsigned int alen; /* len of client addr*/

int msock; /* master server socket */

int ssock; /* slave server socket */

pthread_t tid;

switch (argc) {

case 1: break;

case 2: service = argv[1];

break;

default: errexit("usage: TCPechod [port]\n");

}

Page 25: Sockets Programming in Linux

25

Concurrent Connection-OrientedTCPechod.c

msock = passiveTCP(service, QLEN);

while (1) {

alen = sizeof(fsin);

ssock = accept (msock, (struct sockaddr *)&fsin, &alen);

if (ssock < 0) {

errexit("accept: %s\n", strerror(errno));

}

//Now create a thread to handle client request

pthread_create (&tid, NULL, &TCPechod, (void *)&ssock);

} //end of while

}//end of main

Page 26: Sockets Programming in Linux

26

Concurrent Connection-OrientedTCPechod.c

msock = passiveTCP(service, QLEN);

while (1) {

alen = sizeof(fsin);

ssock = accept(msock, (struct sockaddr *)&fsin, &alen);

if (ssock < 0) {

errexit("accept: %s\n", strerror(errno));

}

//Now create a thread to handle client request

pthread_create (&tid, NULL, &TCPechod, (void *)&ssock);

} //end of while

}//end of main

Page 27: Sockets Programming in Linux

27

Concurrent Connection-OrientedTCPechod.c

void * TCPechod(void * pfd) {

char buf[BUFSIZE];

int cc, fd;

fd = * (int *) pfd;

while (cc = recv(fd, buf, sizeof (buf), 0)) {

if (cc < 0)

errexit("echo read: %s\n", strerror(errno));

printf ("We got: %s\n", buf);

if (send(fd, buf, cc, 0) < 0)

errexit("echo write: %s\n", strerror(errno));

bzero (&buf, sizeof(buf));

}

}

Page 28: Sockets Programming in Linux

28

Summary

• Sockets API almost identical in Windows and Linux– Linux does not use WSAStartup, WSACleanup– Linux uses close(socket), Windows uses

closesocket()• Some differences in Operating System functions

– Multiple threads• Windows - _beginthread (…)• Linux – pthread_create (…)

– Multiple Processes• Windows – CreateProcess(…)• Linux – Fork()