sockets programming in linux
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 PresentationTRANSCRIPT
1
Sockets Programming in Linux
References:
Internetworking with TCP/IP Vol III - Linux version
UNIX Network Programming - W. Richard Stevens
2
Sockets Programming in Linux
• Linux / UNIX Socket API functions
• Example TCP / UDP Clients
• Example TCP / UDP Servers
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
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
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
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 ( )
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)
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]
9
Linux Client - Connectsock.c
int connectTCP (char *host, char *service)
{
return connectsock (host, service, “tcp”);
}
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;
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);
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;}
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);
}
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);
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);}
}
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
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);
}
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);
19
Example Linux Client - UDPecho.c
if (read (s, buf, nchars) < 0)
error_exit (“Socket read failed \n”);
fputs (buf, stdout);
}
}
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*/
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");
}
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));
}
}
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);
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");
}
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
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
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));
}
}
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()