Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

UNIT 2 TCP ECHO SERVER

#include"unp.h"
Int main(intargc, char**argv)
{intlistenfd, connfd;
pid_tchildpid;
socklen_tclilen;
structsockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
str_echo(connfd); /* process the request */
exit(0);
}Close(connfd); /* parent closes connected socket
TCP Echo Server:str_echoFunction
#include"unp.h"
Void str_echo(intsockfd)
{ ssize_tn;
charbuf[MAXLINE]; again:
while( (n = read(sockfd, buf, MAXLINE)) > 0)
Writen(sockfd, buf, n);
if(n < 0&& errno == EINTR)
gotoagain; elseif(n < 0)
err_sys("str_echo: read error");
UNIT 2
TCP Echo Client :str_cliFunction
#include"unp.h"
void
str_cli(FILE *fp, intsockfd)
{
charsendline[MAXLINE], recvline[MAXLINE];
while(Fgets(sendline, MAXLINE, fp) != NULL)
{
Writen(sockfd, sendline, strlen(sendline));
if(Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);
}
}
UNIT 2 1. **`getsockname`**: This function is used to retrieve the local
address and port number of a socket. It is typically called after a socket has
been bound to an address using the `bind` function. The `getsockname`
function takes the socket file descriptor as an argument and fills a `struct
sockaddr` structure with the local address information.
Example:
```c
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
getsockname(sockfd, (struct sockaddr *)&addr, &addr_len);
```
2. **`getpeername`**: This function is used to retrieve the address and port
number of the peer socket to which a connection-oriented socket is
connected. It is typically called on a connected socket (e.g., after a call to
`connect` for TCP sockets). Like `getsockname`, `getpeername` takes the
socket file descriptor as an argument and fills a `struct sockaddr` structure
with the peer's address information.
Example:
```c
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
getpeername(sockfd, (struct sockaddr *)&addr, &addr_len);
The `getsockname` function is used to retrieve the local IP address and port
number assigned to a socket. It is useful after a successful `connect` in a TCP
client without a `bind`, after calling `bind` with a port number of 0, and in a
TCP server that binds the wildcard IP address to obtain the local IP address
assigned to a connection
The `getpeername` function is used to obtain the address and port number
of the peer socket in a connected socket. It is useful for identifying the client
in a server process that has been `exec`ed by the process calling `accept`.
getsockopt and setsockopt Functions:
•sockfd must refer to an open socket descriptor.
•level specifies the code in the system that interprets the option: the general
socket code or some protocol-specific code (e.g., IPv4, IPv6, TCP, or SCTP).
•optval is a pointer to a variable from which the new value of the option is
fetched by getsockopt, or into which the current value of the option is stored
by setsockopt.
•The size of this variable is specified by the final argument, as a value for
setsockopt and as a value-result for getsockopt.
#include ‹sys/socket.h>
int getsockopt(int sockfd, int level, int
optname, void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int
optname, const void *optval socklen_t
optlen);
Both return: 0 if OK, 1 on
There are two basic types of options:
•binary options that enable or disable a certain feature (flags), and
•options that fetch and return specific values that we can either set or
examine (values).
•The column labelled "Flag" specifies if the option is a flag option.
•When calling getsockopt for these flag options, *optval is an integer.
•The value returned in *optval is zero if the option is disabled, or nonzero if
the option is enabled. Similarly, setsockopt requires a nonzero *optval to
turn the option on, and a zero value to turn the option off.
•If the "Flag" column does not contain a "•," then the option is used to pass
a value of the specified datatype between the user process and the system.
SOCKETR FUNCTION FOR UDP CLIENT AND SERVER UNIT 3
There are fundamental differences between applications written using TCP
versus those that use UDP.
•It is because differences in UDP and TCP protocols.
•UDP is a connectionless, unreliable, datagram protocol.
•TCP is connection-oriented, reliable byte stream.
•Applications built using UDP are: DNS, NFS, and SNMP
sendto() and recvfrom()

1. **`getservbyname`**: This function is used to retrieve service information


based on a service name and protocol. It takes a service name (e.g., "http"
for HTTP) and a protocol name (e.g., "tcp" for TCP) as arguments and returns
a pointer to a `struct servent` containing information about the service, such
as its port numbe
Example:
```c
struct servent *service_info;
service_info = getservbyname("http", "tcp");

2. **`getservbyport`**: This function is used to retrieve service information


based on a port number and protocol. It takes a port number and a protocol
name as arguments and returns a pointer to a `struct servent` containing
information about the service, such as its service name.

Example:
```c
struct servent *service_info;
service_info = getservbyport(htons(80), "tcp")
Domain Name Systems(DNS).
•The DNS is used primarily to map between hostnames and IP addresses.
•A hostname can be either a simple name, such as solarisor freebsdor
google.
•A fully qualified domain name (FQDN) such as solaris.unpbook.com.
•An FQDN is also called an absolute name and must end with a DOT, but
users often omit the ending period.
•The trailing DOT tells the resolver that this name is fully qualified and it
doesn't need to search its list of possible domains.

Entries in the DNS are known as resource records (RRs).


•Few types of RRs that are of interest are:
•A-An A record maps a hostname into a 32-bit IPv4 address.
•AAAA-a AAAA record, called a "quad A" record, maps a hostname into a
128-bit IPv6 address.
•The term "quad A" is used because a 128-bit address is four times larger
than a 32-bit address.
•PTR -PTR records (called "pointer records") map IP addresses into
hostnames. PTR records are used for the reverse DNS lookup
Getaddrinfo
struct addrinfo hints, *result;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // Use TCP
getaddrinfo("www.example.com", "http", &hints, &result);
getaddrinfo: This function takes a host name, service name, and a set of
hints (optional) as input and returns a linked list of struct addrinfo structures,
each containing information about a single address that can be used to
connect to the specified host and service.
The `gethostbyname` and `gethostbyaddr` functions are used in network
programming to perform host name resolution and obtain information about
a host. Here's a brief explanation of each:

1. **`gethostbyname`**: This function is used to retrieve host information


based on a host name. It takes a host name as an argument and returns a
pointer to a `struct hostent` containing information about the host, such as
its IP addresses.
Example:
```c
struct hostent *host_info;
host_info = gethostbyname("example.com");

2. **`gethostbyaddr`**: This function is used to retrieve host information


based on an IP address. It takes an IP address in binary form, a length
indicating the size of the address (usually `sizeof(struct in_addr)` for IPv4
addresses), and the address family as arguments. It returns a pointer to a
`struct hostent` containing information about the host
Example:
```c
struct hostent *host_info;
struct in_addr addr;
inet_pton(AF_INET, "192.168.1.1", &addr);
host_info = gethostbyaddr(&addr, sizeof(addr), AF_INET);
```
Socket add structure
Concurrent servers are server programs designed to handle multiple client
requests simultaneously. These servers are capable of serving multiple clients
concurrently without blocking or delaying other clients. There are several
approaches to implementing concurrent servers:

1. **Multi-Process Servers**: Each client connection is handled by a separate


process. The server creates a new process or thread for each incoming
connection, allowing multiple clients to be served concurrently.

2. **Multi-Threaded Servers**: Similar to multi-process servers, but uses


threads instead of processes to handle client connections. Threads share the
same address space, making them more lightweight than processes.

3. **Event-Driven Servers**: These servers use a single-threaded event loop


to manage multiple client connections. Events, such as incoming data or
client connections, are processed asynchronously, allowing the server to
handle multiple clients concurrently without creating additional threads or
processes.

4. **Thread Pool Servers**: These servers maintain a pool of threads that


are used to handle client connections. When a new connection arrives, a
thread from the pool is assigned to handle it. This approach reduces the
overhead of creating and destroying threads for each client connection.

Concurrent servers are commonly used in applications where multiple clients


need to interact with a server simultaneously, such as web servers, chat
servers, and online gaming servers. They provide efficient and scalable
solutions for handling concurrent client requests.
fork and exec Functions
Go, change the world
•fork() and exec() are used in creation of concurrent servers.
•The fork function returns twice.
•It returns once in the calling process (called the parent) with a return value
that is the process ID of the newly created process (the child).
•It also returns once in the child, with a return value of 0.
•The return value tells the process whether it is the parent or the child.
•All descriptors open in the parent before the call to fork are shared with the
child after fork returns.

•In network servers, the parent calls accept and then calls fork.
•The connected socket is then shared between the parent and child.
•Normally, the child then reads and writes the connected socket and the
parent closes the connected socket.
•There are two typical uses of fork:
1.A process makes a copy of itself so that one copy can handle one operation
while the other copy does another task.
2.A process wants to execute another program. Since the only way to create
a new process is by calling fork, the process first calls fork to make a copy of
itself, and then one of the copies (typically the child process) calls exec
(described next) to replace itself with the new program.
Here are some common socket functions used in network programming,
along with their syntax and a brief explanation:

1. **`socket`**: Create a new socket.


int sockfd = socket(domain, type, protocol);
- `domain`: Address family (e.g., `AF_INET` for IPv4).
- `type`: Socket type (e.g., `SOCK_STREAM` for TCP).
- `protocol`: Specific protocol (usually set to 0 for default)
2. **`bind`**: Bind a socket to an address and port.
int status = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
- `sockfd`: Socket file descriptor.
- `addr`: Address structure (`struct sockaddr`)
3. **`listen`**: Set a socket to listen for incoming connections.
int status = listen(sockfd, backlog);
- `backlog`: Maximum number of pending connections.
4. **`accept`**: Accept a connection on a socket.
int new_sockfd = accept(sockfd, (struct sockaddr *)&addr, &addrlen);
- `new_sockfd`: New socket file descriptor for the accepted connection.
- `addr`: Address structure of the client.
- `addrlen`: Pointer to the size of `addr`.
5. **`connect`**: Initiate a connection to a remote host.

int status = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));


6. **`send`**: Send data over a socket.
ssize_t bytes_sent = send(sockfd, buffer, length, flags)
7. **`recv`**: Receive data from a socket.
```c
ssize_t bytes_received = recv(sockfd, buffer, length, flags);
8. **`close`**: Close a socket
int status = close(sockfd)

You might also like