0% found this document useful (0 votes)
87 views

Chapter 3 - Advanced Sockets Functions

This document provides an overview of advanced socket functions in 3 chapters. It describes functions for event notification on sockets like select(), retrieving socket addresses like getsockname(), manipulating socket options like getsockopt()/setsockopt(), terminating a TCP connection like shutdown(), performing domain name lookups like gethostbyname(), and more. Examples of usage are provided for many functions. The document aims to outline these important network programming functions beyond basic sockets.
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
87 views

Chapter 3 - Advanced Sockets Functions

This document provides an overview of advanced socket functions in 3 chapters. It describes functions for event notification on sockets like select(), retrieving socket addresses like getsockname(), manipulating socket options like getsockopt()/setsockopt(), terminating a TCP connection like shutdown(), performing domain name lookups like gethostbyname(), and more. Examples of usage are provided for many functions. The document aims to outline these important network programming functions beyond basic sockets.
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 45

Chapter 3

Advanced Sockets
Functions
By
En. Mohd Nizam bin Osman
(Senior Lecturer)
Department of Computer Science
Faculty of Computer and Mathematical Science, UiTM Perlis
Course Outline
• select
• getsockname
• getpeername
• getsockopt
• shutdown
• gethostname
• gethostbyaddr
• gethostbyname
• getservbyname
• getservbyport
Sockets Function
SOCKETS FUNCTIONS
Function Description
select Provides event notification of socket events
getsockname Returns the address of the local socket
getpeername Returns the address of the remote socket
getsockopt Returns the value of a socket option for a given socket
setsockopt Manipulates a socket option for a given socket
shutdown Closes a socket with more control
gethostname Retrieves the name of the host on which this stack operates
sethostname Sets the name of the host on which this stack operates
gethostbyaddr Returns the FQDN for a given IP address
gethostbyname Returns the IP address for a given FQDN
getservbyname Returns the port number for a given service string
getservbyport Returns the service string for a given port number
Function
select()
int select (int maxDescPlus1, fd_set *readDescs, fd_Set
*writeDescs, fd_set *exceptionDescs, struct timeval
*timeout);
maxDescsPlus1: integer, hint of the maximum number of descriptors
readDescs: fd_set, checked for immediate input availability
writeDescs: fd_set, checked for the ability to immediately write data
exceptionDescs: fd_set, checked for pending exceptions
timeout: struct timeval, how long it blocks (NULL -> forever)
Client/sever model

Provides a notification service for a


Purpose collection of events on one or more
socket
Function
select()
 returns the total number of ready descriptors:
Value Description
>0 Number of descriptors that are contained within the descriptor set
0 Expiration of the timeout argument
-1 An error occurred in the select function

 Changes the descriptor lists so that only the corresponding positions


Client/sever
are set. model
int FD_ZERO (fd_set *descriptorVector); /* removes all descriptors from vector */
int FD_CLR (int descriptor, fd_set *descriptorVector); /* remove descriptor from vector */
int FD_SET (int descriptor, fd_set *descriptorVector); /* add descriptor to vector */
int FD_ISSET (int descriptor, fd_set *descriptorVector); /* vector membership check */

struct timeval{
time_ttv_sec;/* seconds */
time_ttv_usec;/* microseconds */
};
Function
getsockname()
int getsockname(int sockfd, struct sockaddr *addr, socklen_t
Client/sever model
*addrlen);

To return the local address of a given


Purpose socket
returns the current address to which the socket
sockfd is bound, in the buffer pointed to by
addr
0 is returned on success; -1 otherwise
Function
getpeername()
int getpeername(int
Client/sever model sockfd, struct sockaddr *addr,
socklen_t *addrlen);

To return the peer address of a given


Purpose socket (foreign address)

returns the address (IP and port) of the peer connected


to the socket sockfd, in the buffer pointed to by addr
0 is returned on success; -1 otherwise
Function: Socket Options
getsockopt()/setsockopt()
int getsockopt
Client/sever model (int sockid, int level, int optName, void
*optVal, socklen_t optLen);
 sockid: integer, socket descriptor
 level: integer, the layers of the protocol stack (socket, TCP, IP)
 optName: integer, option
 optVal: pointer to a buffer; upon return it contains the value of the specified option
 optLen: integer, in-out parameter
int setsockopt(int sockid, int level, int optName, void

*optVal,
 socklen_t
optLen is now optLen);
only an input parameter
 It returns -1 if an error occurred

getsockopt and setsockopt allow socket


Purpose options values to be queried and set, respectively.
Socket Options
(Table)
Client/sever model
Socket Options
(Example)
“Fetch and then double the current number of bytes in the
Client/sever
socket’s modelbuffer”
receive
int rcvBufferSize;
int sockOptSize;

/* Retrieve and print the default buffer size */
sockOptSize= sizeof(recvBuffSize);
if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvBufferSize,
&sockOptSize) < 0)
DieWithError(“getsockopt() failed”);
printf(“InitialReceive Buffer Size: %d\n”, rcvBufferSize);

/* Double the buffer size */


recvBufferSize*= 2;

/* Set the buffer size to new value */


if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvBufferSize,
sizeof(rcvBufferSize)) < 0)
DieWithError(“getsockopt() failed”);
Function
shutdown()
int shutdown (int socket, int direction);
socket – A socket descriptor created by the socket
system call.
direction – the direction in which shutdown is desired: 0
means terminate further input, 1 means terminate further
output, and 2 means terminate both input and output

 Returns 0 if successful and -1 an error has occurred.

Terminates a TCP connection in one or


Purpose both directions.
Function
gethostname()
int gethostname(char
Client/sever model *hostname, size_t size);
hostname - is a pointer to an array of chars that will contain
the hostname upon the function's return,
size - is the length in bytes of the hostname array.

 It returns the name of the computer that your program is running


on.
 The function returns 0 on successful completion, and -1 on error.

Permits the application to identify the


Purpose name of the host
Function: Domain Name Service
gethostbyaddr()
struct hostent *gethostbyaddr(const void *addr,
socklen_t len, int type);
 returns a structure of type hostent for the given host address
addr of length len and address type type.
Used to identify the fully qualified domain name
Purpose of a host given its IP address
type struct hostent{
char *h_name; /* official name of host */
char **h_aliases; /* alias list (strings) */
int h_addrtype; /* host address type (AF_INET) */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses (binary in network byte order)*/
}
#define h_addrh_addr_list[0] /* for backward compatibility */
Function: Domain Name Service
gethostbyname()
struct hostent
Client/sever model *gethostbyname(const char
*name);
 returns a structure of type hostent for the given host name.
 name is a hostname, or an IPv4 address in standard dot notation.
 e.g. gethostbyname(“www.csd.uoc.gr”);

Used to identify the IP address given a fully qualified


Purpose domain name

type struct hostent{


char *h_name; /* official name of host */
char **h_aliases; /* alias list (strings) */
int h_addrtype; /* host address type (AF_INET) */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses (binary in network byte order)*/
}
#define h_addrh_addr_list[0] /* for backward compatibility */
Function: Domain Name Service
getservbyname()
struct servent *getservbyname(const char
*name, const char *proto);
 returns a servent structure for the entry from the database that matches
the service name using protocol proto.
 if proto is NULL, any protocol will be matched.
 Example: getservbyname(“echo”, “tcp”) ;
Takes a service name and protocol and yields among
Purpose other things, the port to be used to either register the
service or find the service.
struct servent{
char *s_name; /*official service name*/
char **s_aliases; /*list of alternate names(strings)*/
int s_port; /*service port number*/
char *s_proto; /*protocol to use (“tcp” or “udp”)*/
}
Function: Domain Name Service
getservbyport()
struct servent *getservbyport(int port, const
Client/sever model
char *proto);

 returns a servent structure for the entry from the database


that matches the service name using port port
To identify the service and its characteristics given a port
Purpose number

struct servent{
char *s_name; /*official service name*/
char **s_aliases; /*list of alternate names(strings)*/
int s_port; /*service port number*/
char *s_proto; /*protocol to use (“tcp” or “udp”)*/
}
Useful Functions
 int atoi (const char *nptr);
Client/sever
Convertsmodel
the initial portion of the string pointed to by nptr to int
 int inet_aton(const char *cp, struct in_addr *inp);
Converts the Internet host address cp from IPv4 numbers-and-dots
notation into binary form (in network byte order)
Stores it in the structure that inp ponts to.
It returns nonzero if the address is valid, and 0 if not
 char *inet_ntoa(struct in_addr in);
Converts the Internet host address in, given in network byte order,
to a string in IPv4 dotted-decimal notation
typedef uint32_t in_addr_t;

struct in_addr{
int_addr_t s_addr;
};
Iterative Stream Socket Server
 Handles one client at a time.
Client/sever model
 Additional clients can connect while one is being
served.
 Connections are established.
 They are able to send requests.
 But, the server will respond after it finishes with the first
client.
 Works well if each client required a small, bounded
amount of work by the server.
× Otherwise, the client experience long delays.
Iterative Stream Socket Server
 Handles one client at a time.
Client/sever model
 Additional clients can connect while one is being
served.
 Connections are established.
 They are able to send requests.
 But, the server will respond after it finishes with the first
client.
Works well if each client required a small,
bounded amount of work by the server.

Otherwise, the client experience long


delays.
Iterative Server
Example: “Echo Server” using stream socket
//Iterative Server
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>

#define MAXLINE 4096 /*max text line length*/


#define SERV_PORT 3000 /*port*/
#define LISTENQ 8 /*maximum number of client connections */

int main ()
{
int listenfd, connfd, n;
socklen_t clilen;
char buf[MAXLINE];
struct sockaddr_in cliaddr, servaddr;

//creation of the socket


listenfd = socket (AF_INET, SOCK_STREAM, 0);
Iterative Server
Example: “Echo Server” using stream socket
//preparation of the socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);

bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

listen(listenfd, LISTENQ);

printf("%s\n","Server running...waiting for connections.");

for ( ; ; ) {

clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
printf("%s\n","Received request...");

while ( (n = recv(connfd, buf, MAXLINE,0)) > 0) {


printf("%s","String received from and resent to the client:");
puts(buf);
send(connfd, buf, n, 0);
}
Iterative Server
Example: “Echo Server” using stream socket
if (n < 0) {
perror("Read error");
exit(1);
}
close(connfd);

}
//close listening socket
close(listenfd);
}
Iterative Server
Example: “Echo Server” using stream socket
//Client
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

#define MAXLINE 4096 /*max text line length*/


#define SERV_PORT 3000 /*port*/

int main()
{
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXLINE], recvline[MAXLINE];

//Create a socket for the client


//If sockfd<0 there was an error in the creation of the socket
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
perror("Problem in creating the socket");
exit(2);
}
Iterative Server
Example: “Echo Server” using stream socket
//Creation of the socket
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr= inet_addr("127.0.0.1");
servaddr.sin_port = htons(SERV_PORT); //convert to big-endian order

//Connection of the client to the socket


if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {
perror("Problem in connecting to the server");
exit(3);
}

printf("Please enter string from the client: ");


while (fgets(sendline, MAXLINE, stdin) != NULL) {

send(sockfd, sendline, strlen(sendline), 0);

if (recv(sockfd, recvline, MAXLINE,0) == 0){


//error: server terminated prematurely
perror("The server terminated prematurely");
exit(4);
}
Iterative Server
Example: “Echo Server” using stream socket
printf("%s", "String received from the server: ");
fputs(recvline, stdout);
printf("Please enter string from the client: ");
}

exit(0);
}
Multitasking – Per-Client Process
For each client connection request, a new process is
Client/sever model
created to handle the communication.
int fork();
A new process is created, identical to the calling
process, except for its process ID and the return value it
receives from fork().
Return 0 to child process, and the process ID of the
new child to parent.

When a child process Use waitpid() to


terminates, it does not parent in order to
automatically disappears “harvest” zombies.
Multitasking – Per-Client Process
fork()
int fork(void);
Client/sever model

The fork function creates a new process.


The new process called the child process will be an exact
copy of the calling process (parent process). The child
process inherits many attributes from the parent process.
Upon successful completion, fork() returns 0 to the child
process and the process ID of the child process to the parent
process.
Otherwise -1 is returned to the parent process, no child
process is created and errno is set to indicate the error.
Multitasking – Per-Client Process
Example: fork()
#include <stdio.h> void ChildProcess(void)
#include <sys/types.h> {
 
Client/sever model
int i;
#define MAX_COUNT 200  
  for (i = 1; i <= MAX_COUNT; i++)
void ChildProcess(void); printf(" This line is from
/* child process prototype */ child, value = %d\n", i);
void ParentProcess(void); printf(" *** Child process
/* parent process prototype */ is done ***\n");
  }
void main(void)  
{ void ParentProcess(void)
pid_t pid; {
  int i;
pid = fork();  
if (pid == 0) for (i = 1; i <= MAX_COUNT; i++)
ChildProcess(); printf("This line is from
else parent, value = %d\n", i);
ParentProcess(); printf("*** Parent is done
} ***\n");
}
Multitasking – Per-Client Process
Example
To allow the server to handle multiple simultaneously
Client/sever model
connection:

Put the accept statement


After a connection is established, call
and the following code in an fork() to create a new process
infinite loop

The child process will close sockfd and call


doprocessing function, passing the new The parent process close newsockfd.
socket file descriptor as an argument. When
the two processes have completed their
As all of this code is in an infinite loop,
conversation, as indicated by it will return to the accept statement
doprocessing() returning, this process to wait for the next connection
simply exits.
Multitasking – Per-Client Process
Example: using fork()
//Server /* Initialize socket structure */
#include <stdio.h> bzero((char *) &serv_addr,
Client/sever model
#include <stdlib.h> sizeof(serv_addr));
portno = 5001;
#include <netdb.h>
#include <netinet/in.h> serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
#include <string.h> serv_addr.sin_port = htons(portno);

void doprocessing (int sock); /* Now bind the host address using bind()
call.*/
int main( int argc, char *argv[] ) { if (bind(sockfd, (struct sockaddr *)
int sockfd, newsockfd, portno, clilen; &serv_addr, sizeof(serv_addr)) < 0) {
char buffer[256]; perror("ERROR on binding");
struct sockaddr_in serv_addr, cli_addr; exit(1);
int n, pid; }

/* First call to socket() function */ /* Now start listening for the clients,
sockfd = socket(AF_INET, SOCK_STREAM, 0); here process will go in sleep mode and
will wait for the incoming connection
if (sockfd < 0) { */
perror("ERROR opening socket");
exit(1);
}
Multitasking – Per-Client Process
Example: using fork()
listen(sockfd,5); else {
clilen = sizeof(cli_addr); close(newsockfd);
Client/sever model }
while (1) { } /* end of while */
newsockfd = accept(sockfd, (struct }
sockaddr *) &cli_addr, &clilen);
void doprocessing (int sock) {
if (newsockfd < 0) { int n;
perror("ERROR on accept"); char buffer[256];
exit(1); bzero(buffer,256);
} n = read(sock,buffer,255);

/* Create child process */ if (n < 0) {


pid = fork(); perror("ERROR reading from socket");
exit(1);
if (pid < 0) { }
perror("ERROR on fork"); printf("Here is the message: %s\n",buffer);
exit(1); n = write(sock,"I got your message",18);
}
if (pid == 0) { if (n < 0) {
/* This is the client process */ perror("ERROR writing to socket");
close(sockfd); exit(1);
doprocessing(newsockfd); }
exit(0); }
}
Multitasking – Per-Client Process
Example: using fork()
//Client /* Create a socket point */
#include <stdio.h> sockfd = socket(AF_INET, SOCK_STREAM, 0);
Client/sever model
#include <stdlib.h>
#include <netdb.h> if (sockfd < 0) {
#include <netinet/in.h> perror("ERROR opening socket");
#include <string.h> exit(1);
}
int main(int argc, char *argv[]) {
int sockfd, portno, n; server = gethostbyname(argv[1]);
struct sockaddr_in serv_addr;
struct hostent *server; if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
char buffer[256]; exit(0);
}
if (argc < 3) {
fprintf(stderr,"usage %s hostname bzero((char *) &serv_addr,
port\n", argv[0]); sizeof(serv_addr));
exit(0); serv_addr.sin_family = AF_INET;
} bcopy((char *)server->h_addr, (char *)
&serv_addr.sin_addr.s_addr,
portno = atoi(argv[2]); server->h_length);
serv_addr.sin_port = htons(portno);
Multitasking – Per-Client Process
Example: using fork()
/* Now connect to the server */ /* Now read server response */
if (connect(sockfd, (struct sockaddr*) bzero(buffer,256);
Client/sever model
&serv_addr, sizeof(serv_addr)) < 0) { n = read(sockfd, buffer, 255);
perror("ERROR connecting");
exit(1); if (n < 0) {
} perror("ERROR reading from socket");
exit(1);
/* Now ask for a message from the user, }
this message will be read by server
*/ printf("%s\n",buffer);
return 0;
printf("Please enter the message: "); }
bzero(buffer,256);
fgets(buffer,255,stdin);

/* Send message to the server */


n = write(sockfd, buffer, strlen(buffer));

if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
Multitasking – Per-Client Thread
Client/sever
Forkingmodela new process is expensive.
Duplicate the entire state (memory, stack,
file/socket descriptors, ….)
Threads decrease this cost by allowing
multitasking within the same process.
Threads share the same address space (code
and data)
An example is provided using POSIX
Threads
Multitasking – Per-Client Thread
Example: echo using stream socket
Client/sever model
Multitasking – Per-Client Thread
Example: echo using stream socket
Client/sever model
Multitasking – Constrained
Both process and thread incurred overhead.
Client/sever
 Creation, model
scheduling and context switching
As their numbers increases:
 This overhead increases
 After some point it would be better if a client was blocked
Solution: Constrained multitasking. The server:
 Begins, creating, binding and listening to a socket
 Creates a number of processes, each loop forever and
accept connections from the same socket.
 When a connection is established:
 The client socket descriptors is returned to only one process.
 The other remain blocked.
Multitasking – Constrained
Example: echo using stream socket
Client/sever model
Multiplexing
 So far, we have dealt with a single I/O channel.
Client/sever model
 We may need to cope with multiple I/O channels.
E.g., supporting the echo service over multiple ports.
 Problem: From which socket the server should accept
connections or receive messages?
It can be solved using non-blocking sockets.
But it requires polling
 Solution: select()
Specifies a list of descriptors to check for pending I/O
operations.
Blocks until one of the descriptors is ready.
Returns which descriptors are ready.
Multiplexing
Example: echo using stream socket
Client/sever model
Multiplexing
Example: echo using stream socket
Client/sever model
Multiple Recipients
 So far, all sockets have dealt with unicast communication.
Client/sever model
i.e., an one-to-one communication, where one copy (“uni”) of the
data is sent (“cast”)
 What if we want to send data to multiple recipients?
1st Solution: unicast a copy of data to each recipient
Inefficient, e.g.,
Consider we are connected to the internet through a 3Mbps
line
A video server send 1-Mbps streams
Then, server can support only three clients simultaneously.
2nd Solution: using network support
Broadcast, all the host of the network receive the message.
Multicast, a message is sent to some subset of the host
For IP, only UDP sockets are allowed to broadcast and multicast.
Multiple Recipients
Broadcast
 Only the IP address changes
Client/sever model
 Local broadcast: to address 255.255.255.255
Send the message to every host on the same broadcast network
Not forwarded by routers
 Directed broadcast:
For network identifier 169.125 (i.e., with subnet mask
255.255.0.0)
The directed broadcast address is 169.125.255.255

In order to use broadcast the options of socket must change:


int bradcastPermission = 1;
setsocopt (soc, SOL_SOCKET,SO_BROADCAST, (void*)
&broadcastPermission, sizeof(broadcastPermission));
Multiple Recipients
Multicast
Client/sever
Using class model
D addresses
Range from 224.0.0.0 to 239.255.255.255
Hosts send multicast request for specific
addresses
A multicast group formed
We need to set TTL (time-to-live), to limit the
number of hops
Using sockopt()
No need to change the options of socket
The End
Q&A

You might also like