Chapter: Network Programming and Management : Socket Options, Elementary UDP SOC Sockets

UDP Echo Client

An IPv4 socket address structure is filled in with the IP address and port numbers of the server. This structure is passed on to dg_cli.

UDP Echo Client :

udpcliserv/ udpcli01.c Page No: 216

#include     "unp.h"

 

int

main(int argc, char **argv)

 

{

int    sockfd;

 

struct sockaddr_in        servaddr;

if (argc != 2)

 

err_quit("usage: udpcli <IPaddress>"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

 

dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); exit(0);

 

}

 

An IPv4 socket address structure is filled in with the IP address and port numbers of the server. This structure is passed on to dg_cli.

A UDP socket is is created and the function calls dg_cli.

 

Dg_cli Function

 

#include     "unp.h"

 

void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

 

{

int    n;

char sendline[MAXLINE], recvline[MAXLINE + 1];

 

while (Fgets(sendline, MAXLINE, fp) != NULL) {

 

sendto (sockfd, sendline, strlen(sendline, 0, pservaddr, servlen);

 

n = recvfrom(sockfd, recvline, MAXLINE,0,NULL,NULL);

 

recvline[n] = 0; /* null terminate */ Fputs(recvline, stdout);

}

 

}

 

 

With a UDP socket, when the first time the call to sendto() is given, the port is bound to it. Also similar to server, client can also call for bind() to tie up its port.

 

In the recvfrom(), a null pointer is specified in the fifth and sixth argument. Which means that we are not interest in knowing who has send the datagram. This may result in error in reception of datagram, as the same host or any other host may send datagram which is likely to be mistaken.

 

Similar to dg_echo(), dg_cli() is also protocol independent. In this the main function allocates and initializes a socket address structure of some protocol type and then passes pointer to this structure along with its size.

 

Lost Datagrams:

 

Above client server example is not reliable. If the client datagram is lost, (may be dropped at any router), the client will block its recvfrom() forever waiting for a server reply that will never arrive. Similarly if the client datagram arrives at the server but the server‘s reply is lost, the client will once again block the recvfrom(). A time out and a appended number is normally sent with the datagram which is sent back as acknowledgment with reply. This will assure whether the datagram is received or not. This facility is provided many UDP servers.

 

Verifying the Received Response : It is seen from the above example that any process that knows the clients ephemeral port number could datagram to our client and these will be interpreted with the normal server replies. It can be avoided by comparing the IP address and port number of the recvfrom() (reply received from server), with that of the IP address and port number to which it was sent earlier. This requires creating a socket address structure in which the return address structure is returned and

 

compared with  the sent  address structure. This  is shown in the following example

 

udpcliserv/dgcliaddr.c  Page No : 219

dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

 

{

int                                  n;

char                      sendline[MAXLINE], recvline[MAXLINE + 1];

socklen_t             len;

struct sockaddr    *preply_addr;

prpeply_addr = malloc(servlen);

 

while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); Len = servlen;

 

n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); if (len != servlen|| memcmp (pservaddr, preply_addr, len)!= 0) {printf (reply from %s (ignored)\n―),sock_ntop (preply_addr, len);

continue;

}

Recvline[n] = 0;   /* null terminate */

 

Fputs(recvline, stdout);

}

}

 

 

First the, client main function is changed to use the standard echo server. Servaddr.sin_port = htons(SERV_PORT) changed to servaddr.sin_port = htons (7). Malloc() function allocates the byte size to the structure. With this arrangement, the received address captured in preply_addr is compared with the one that was sent in sendto(). First a comparison is made of its length and then memcopy compares then socket address itself is compared. This will assure if the server address is same.

 

However, even this may not work if the server is multi homed where in it is likely to allocate different IP address as the server has not bound an IP address to its socket and it chooses any IP Address. Hence this may also fail.

 

One solution is                                                              for the client to verify the responding host‘s                                                         domain name instead of its IP

address by looking up the server‘s name in the DNS, given the IP address returned by recvfrom().

 

Another solution is for the server to create one socket for every IP address that is configured on the host , bind that IP address to the socket, use select across all these sockets (waiting for one to be readable) and then reply from the socket that is readable. Since the socket used for the reply was bound to the IP address that was the destination address of the client request, this guarantees that the source address for the reply is the same as the destination address of the request.

Server not Running :

If the client sends a datagram to a server that is not yet started, what happens to it? The recvfrom() will be blocked for ever waiting for a reply from the server. When the call to sendto() is given by passing the massage to it, the function returns OK ( size of message to application) which means that datagram is put in the output interface queue for further transmission. Where as the datagram traveling to server that is not switched on, is responded with an ICMP port unreachable error. As this error takes more time to return (equal to RTT), this error is known as asynchronous error - not synchronous with the error causing source, which in this case is sendto().

This error is not returned to UDP socket at the client. Hence, the recvfrom() is left open. The asynchronous error can be returned only when the socket have been connected which requires a call to connect() by the client.

 

connect() with UDP:

 

As it was seen that asynchronous errors are not returned to UDP sockets unless the socket has been connected. It is possible to give a call to connect() in UDP also. But it does involved few changes that are listed below:

 

1. When connect() is called, the destination IP address and port number of the server host is provided. Hence there is no requirement to pass these values in sendto(). Hence, the functions sendto() is replaced with write() or send() functions. This assumes that anything written is automatically send to the server address specified in the connect function.

2. Similarly, recvfrom() is also not used instead recv() or read() functions are used. The only datagram returned by the kernel for an input operation on a connected UDP socket are those arriving from protocol address specified in the connect. Datagram destined to the connected UDP sockets local protocol address but arriving from a protocol address other than the one to which the socket was connected, are not passed to the connected socket. This limits the connected UDP socket to exchanging datagram with one and only peer.

3 Asynchronous errors are returned to the process for a connected UDP socket. Also an unconnected UDP sockets does not receive any asynchronous error.

 

It can be said that UDP client or server can call connect() only if that process uses UDP socket to communicate with exactly one peer.

Calling connect () Multiple Times for a UDP socket:

A process with a connected UDP socket can call connect() function again for that socket to either

 

         Specify a new IP address and p ort or to,

 

         Unconnect the socket.

 

Unlike in the case of TCP, where in the connect() is called only once, in the case of UDP, it can be called again.

 

To unconnect, the connect is called by setting the family members of the socket address structure (sin_family for IPv4 and sin6_family for IPv6) to AF_UNSPEC. This might return EAFNOSUPPORT error but it is accepted.

 

Performance:

 

When an application calls sendto() on an unconnected UDP socket, Berkeley derived kernels temporarily connect the socket, and datagram and then un connect the socket . Calling sendto for two datagram on unconnected UDP socket then involves the following six steps:

 

         Connect  the socket.

 

         Output the first datagram.

 

         Unconnect the socket.

 

         Connect the socket.

 

         Output the second datagram

 

         Unconnect the socket.

 

When the application knows that it will be sending multiple datagram to the same peer, it is more efficient to connect the socket explicitly by calling connect() function and then call write() function as many times. As shown below:

 

         Connect the socket/

 

         Output the first datagram and

 

         Output the second datagram.

 

IN this case the kernel copies only the socket address structure containing the destination IP address and port one time, versus two times when sendto is called twice.

 

The dg_cli function with call to connect function is given below:

 

#include      "unp.h"

 

void

 

dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

{       int               n;

char  sendline[MAXLINE], recvline[MAXLINE + 1];

Connect(sockfd, (SA *) pservaddr, servlen);

 

while (Fgets(sendline, MAXLINE, fp) != NULL) { Write(sockfd, sendline, strlen(sendline));

 

n = Read(sockfd, recvline, MAXLINE); recvline[n] = 0; /* null terminate */ Fputs(recvline, stdout);

 

} }

 

The changes are the new call to connect and replacing the calls to sendto() and recvfrom() with calls to write() and read(). This functions are still protocol independent.

 

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail
Network Programming and Management : Socket Options, Elementary UDP SOC Sockets : UDP Echo Client |


Privacy Policy, Terms and Conditions, DMCA Policy and Compliant

Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.