You are on page 1of 33

SOCKET

A SOCKET INIP UNIX


IS BASICALLY ADDRESS + PORT
NO.NOW everything in Unix is a file!”
when Unix programs do any sort of I/O,
they do it by reading or writing to a file
descriptor.A file descriptor is simply an in-
teger associated with an open file.So
when you want to communicate with an-
other program
over the Internet you're gonna do it
through a file descriptor.To get a file
descriptor for network communication You
make a call to the socket()system routine. It re-
turns the socket descriptor, and you
communicate through it using the special-
What is a socket?
Socket: An interface between an application process
and transport layer

The application process can send/receive messages


to/from another application process (local or remote)via
a socket

In Unix , a socket is a file descriptor . an integer


associated with an open file

Types of Sockets: stream sockets,datagram sockets.

Internet sockets characterized by IP Address (4 bytes)


and port number (2 bytes)
Types of Internet Sockets

Stream Sockets (SOCK_STREAM)

Connection oriented
Rely on TCP to provide reliable two way
connectedcommunication

Datagram Sockets (SOCK_DGRAM)


Rely on UDP
Connection is unreliable
Socket Description
Client-server interaction
The entire client-server operation
This client-server progs are working on following principles:

The server is listening and waiting for a connection from the cli-
ent.these server can process 10 clients by using child processes for
each new client.
When the client connects to the server the server creates a new file
descriptor using accept() and creates a new child process using
fork()
Now using send() the server sends a “ Hello,World!” message to the
client
which is accepted by the client using recv()
Now the client displays this “Hello,World!” message on the screen
If there is a error in any of these processes than a error message is
displayed
Basic server operation

Often, there will only be one server on a machine, and


that server will handle multiple clients using fork().

The basic routine is: server will wait for a connection,


accept() it, and fork() a child process to handle it.
Server description
IN the socket prog 1st sockfd → listen on sockfd and new_fd →
new conncn on new_fd is declared
Then hints,*servinfo,*p are declared as struct addrinfo variable
and pointers resp which will take care of addressing and look-
up.
Then their_addr is declared as a struct sockaddr_storage variable this
stores the connecting clients address
Then all the initialization is done by setting the struct addrinfo memory
empty,setting ip family to accept both(ipv4 or ipv6),ip socket type to
sock_stream,and flag to ai_passive so that it uses its own ip address.
Then using getaddrinfo the whole ip,port info is added to the struct ad-
drinfo hints and a pointer servinfo is attached to it.
Now pointer p is assigned to servinfo and a socket descriptor sockfd is
formed using socket() func
Next using setsockopt all the unused ports can be reused.
Then using bind() we can associate a socket with a port on the local ma-
chine.
Now after using servinfo u can free it using freeaddrinfo.
Now the server listens on the port for a new conn
Now the server enters a infinite loop and services the requests from the
clients and creates new descriptors new_fd for a new client
Server contd.......................

The server now uses inet_ntop to convert the structure


where the ip addr is located to number representation
and stores the ip addr to a array s[ ].
Now for every new client it creates a descriptor and
assingns it to a child process
Now the listner sockfd is closed for this client using
close(sockfd).
Now the server uses send() method to send “Hello,World”
message to the client
After the whole process the client's connection is broken
using close(new_fd).
server.c
Header files used in server.c

#include<stdio.h> - used for standard i/o


#include<stdlib.h> - standard library defn.
#include<unistd.h> -defines miscellaneous symbolic con-
stants and types, and declares
miscellaneous funcn.
#include <errno.h> - It defines macros to report error conditions
through error codes
#include<string.h> - string related funcn
#include<sys/types.h> - defn of various datatypes.
#include<sys/socket.h> - internet protocol family structures
#include<netinet/in.h> - internet address family structures
#include<netdb.h> - defn for N/W database operatn.
#include <arpa/inet.h> - defn for internet operatn.
#include <sys/wait.h> - declaratn for waiting
#include <signal.h> - signal handling
cont...

#define PORT "3490" → the port where users will con-


nect .

#define BACKLOG 10 → the no of pending connections


The server queue may support.
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx

char sa_data[14]; // 14 bytes of protocol address


};

struct sockaddr → holds socket address informa-


tion for many types of sockets.
sa_family → AF_INET(IP V4) or AF_INET6(IPV6)
sa_data → contains a destination address and port
number for the socket.
To deal with struct sockaddr, programmers created a parallel
structure: struct sockaddr_in (“in” for “Internet”) to be used
with IPv4.a pointer to a struct sockaddr_in can be cast to a
pointer to a struct sockaddr and vice-versa.

struct sockaddr_in {

short int sin_family; // Address family, AF_INET

unsigned short int sin_port; // Port number

struct in_addr sin_addr; // Internet address

unsigned char sin_zero[8]; // Same size as struct sockaddr


};
socket structures

struct sockaddr:
Holds socket address information for
many types of sockets

struct sockaddr {
unsigned short sa_family; //address family AF_xxx
unsigned short sa_data[14]; //14 bytes of protocol addr
}

struct sockaddr_in:
A parallel structure that makes it
easy to reference elements of the socket address

struct sockaddr_in {
short int sin_family; // set to AF_INET
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; //set to all zeros
}
cont..
struct addrinfo
struct addrinfo {
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
int ai_protocol; // use 0 for "any"
size_t ai_addrlen; // size of ai_addr in bytes
struct sockaddr *ai_addr; // struct sockaddr_in or _in6
char *ai_canonname; // full canonical hostname
struct addrinfo *ai_next; // linked list, next node
};
struct addrinfo is used to prep the socket address structures for
subsequent use. It's also used in host name lookups, and service name
lookups.
Initialization code
int status;
struct addrinfo hints;

struct addrinfo *servinfo;


will point to the results

memset(&hints, 0, sizeof hints);


make sure the struct is empty

hints.ai_family = AF_UNSPEC;
don't care IPv4 or Ipv6

hints.ai_socktype = SOCK_STREAM;
TCP stream sockets

hints.ai_flags = AI_PASSIVE;
fill in my IP for me
getaddrinfo()

int getaddrinfo(
const char *node, // "www.example.com" or IP
const char *service, // e.g. "http" or port number
const struct addrinfo *hints,
struct addrinfo **res);

The node parameter is the host name to connect to, or an IP ad-


dress.

the parameter service, which can be a port number, like “80”

hints parameter points to a struct addrinfo.

res is a pointer that points to the results.


socket
socket() -- Get the file descriptor

syntax:
int socket(int domain, int type, int protocol);

domain should be set to AF_INET

type can be SOCK_STREAM or SOCK_DGRAM

set protocol to 0 to have socket choose the cor-


rect protocol based on type

socket() returns a socket descriptor for use in later


system calls or -1 on error
BIND()
bind() - what port am I on?

Used to associate a socket with a port on the local machine


The port number is used by the kernel to match an incoming
packet to a process

int bind(int sockfd, struct sockaddr *my_addr, int addrlen)

sockfd is the socket descriptor returned by socket()


my_addr is pointer to struct sockaddr that contains information
about your IP address and port
addrlen is set to sizeof(struct sockaddr)
returns -1 on error
connect()
connect() - Hello!

Connects to a remote host

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)

sockfd is the socket descriptor returned by socket()

serv_addr is pointer to struct sockaddr that contains informa-


tion on
destination IP address and port addrlen is set to

sizeof(struct sockaddr)

returns -1 on error

At times, you don't have to bind() when you are using


connect()
listen()

listen() - Call me please!

Waits for incoming connections

int listen(int sockfd, int backlog);

sockfd is the socket file descriptor returned by socket()

backlog is the number of connections allowed on the incoming queue


listen() returns -1 on error

Need to call bind() before you can listen()


accept()
accept() - Thank you for calling !

accept() gets the pending connection on the port you are listen()ing on

int accept(int sockfd, void *addr, int *addrlen);

sockfd is the listening socket descriptor information about incoming


connection is stored in

addr which is a pointer to a local struct sockaddr_in

addrlen is set to sizeof(struct sockaddr_in)

accept returns a new socket file descriptor to use for this accepted
connection and -1 on error
working
// make a socket, bind it, and listen on it:

sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

bind(sockfd, res->ai_addr, res->ai_addrlen);

listen(sockfd, BACKLOG);

// now accept an incoming connection:

addr_size = sizeof their_addr;

new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);

// ready to communicate on socket descriptor new_fd!


Send &recieve
send() - Let's talk!

The two functions are for communicating over stream


sockets or connected datagram sockets.

int send(int sockfd, const void *msg, int len, int flags);

sockfd is the socket descriptor you want to send data to


(returned by socket() or got with accept())

msg is a pointer to the data you want to send

len is the length of that data in bytes

set flags to 0 for now

send() returns the number of bytes actually sent (may be less


than the number you told it to send) or -1 on error
Cont.. send & rec
receive()-let's talk

syntax:
int recv(int sockfd, void *buf, int len, int flags);

sockfd is the socket descriptor to read from

buf is the buffer to read the information into

len is the maximum length of the buffer

set flags to 0 for now

recv() returns the number of bytes actually read into the


buffer or -1 on error

If recv() returns 0, the remote side has closed connection


on you
close()

close() - Bye Bye!

int close(int sockfd);

Closes connection corresponding to the socket descriptor and


frees the socket descriptor Will prevent any more sends and
recvs
setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))
This code is added to reuse the port which was used for some oth-
er connectn previously but was still hanging in the kernel.

freeaddrinfo(servinfo);
all done with this structure free the linked-list
struct sockaddr_storage their_addr; // connector's address informa-
tion
char s[INET6_ADDRSTRLEN];//space to hold the IPv4 string

inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);

This funcn converts string IP addresses to their binary rep-


resentations.
Child processes
if (!fork()) { // this is the child process

close(sockfd); // child doesn't need the listener

if (send(new_fd, "Hello, world!", 13, 0) == -1)

perror("send");error has occurred

close(new_fd);//close connection

exit(0);//exit
}
close(new_fd); // parent doesn't need this
}
return 0;
}
Basic client operation
The client gets the server ip address from the command prompt

Using getaddrinfo() the important structs are filled out with relev-
ant info.the info is server ip address and port no to connect to.

Now the socket is formed using the domain,type & protocol and
stored in socket descriptor

Now using connect the client connects to the server.connect fun-


cn contains the sockfd(sock descriptor),a pointer to struct sock-
addr() which contains the info on ip addr & port no.& the last is
the
sizeof (struct sockaddr)
cont..
In the beginning the sockfd ,MAXDATASIZE 100 macro is
declared.
Int buf[MAXDATASIZE] means that the buffer we can input
max 100 bytes of data in the buffer.
Then we declare a structure hint using struct addrinfo hints
We declare 2 pointers to addinfo i.e *servinfo & *p
Struct addrinfo is used to prepare the the address struc-
tures
Then we initialize the hints structure to support both
ipv4,ipv6 and to support a sock_stream kind of socket
getaddrinfo helps in filling up the imp structs with ip
addr,port etc.of the server.i.e these is stored in hints
structure which is also pointed by serinfo pointer.
Similarly socket() is used to return a socket descriptor
Then we associate pointer p to servinfo and inturn to hints
and search through all the results and then pass struct
elements as parameters to socket and return a socket
descriptor.
Connect() is used to connect to a remote host
inet_ntop
inet_ntop(p->ai_family,
get_in_addr((struct sockaddr *)p-
>ai_addr),
s, sizeof s);

The struct addrinfo holds the server info


inet_ntop func converts this struct info to
numbers or dot representation
The parameters passed to this are address
type(ipv4 or ipv6),the adress,a pointer to a
string to store the result,the max length of
the string
cont..client
if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1)

The recv func returns the no. of bytes actually read in the buffer,0 if conn is
closed,-1 if error.

{
perror("recv");//if error occurs.
exit(1);exit.
}
buf[numbytes] = '\0';

This statement stores '\0' that is end of string character in buf array when
transfer of data is over.

printf("client: received '%s'\n",buf);

Display the data received in the buffer from the server.

close(sockfd);//close the socket descriptor


return 0;
}

You might also like