Socket Programming

  Home  Computer Programming  Socket Programming


“Socket Programming Interview Questions and Answers will guide us now that in computing, network programming, essentially identical to socket programming or client-server programming, involves writing computer programs that communicate with other programs across a computer network. The program or process initiating the communication is called a client process, and the program waiting for the communication to be initiated is the server process. Learn Socket Programming with this Interview guide”



62 Socket Programming Questions And Answers

21⟩ What this function socket() does?

Socket Creation Using socket()

#include <sys/types.h>

#include <sys/socket.h>

int socket(int af, int type, int protocol)

socket() is very similar to socketpair() except that only one socket is created instead of two. This is most commonly used if the process you wish to communicate with is not a child process. The af, type, and protocol fields are used just as in the socketpair() system call.

On success, a file descriptor to the socket is returned. On failure, -1 is returned and errno describes the problem.

 184 views

22⟩ What this function bind() does?

Giving a Socket a Name - bind()

#include <sys/types.h>

#include <sys/socket.h>

int bind(int s, struct sockaddr *name, int namelen)

Recall that, using socketpair(), sockets could only be shared between parent and child processes or children of the same parent. With a name attached to the socket, any process on the system can describe (and use) it.

In a call to bind(), s is the file descriptor for the socket, obtained from the call to socket(). name is a pointer to a structure of type sockaddr. If the address family is AF_UNIX (as specified when the socket is created), the structure is defined as follows:

struct sockaddr {

u_short sa_family;

char sa_data[14];

};

name.sa_family should be AF_UNIX. name.sa_data should contain up to 14 bytes of a file name which will be assigned to the socket. namelen gives the actual length of name, that is, the length of the initialized contents of the data structure.

A value of 0 is return on success. On failure, -1 is returned with errno describing the error.

Example:

struct sockaddr name;

int s;

name.sa_family = AF_UNIX;

strcpy(name.sa_data, "/tmp/sock");

if((s = socket(AF_UNIX, SOCK_STREAM, 0) < 0)

{

printf("socket create failure %dn", errno);

exit(0);

}

if (bind(s, &name, strlen(name.sa_data) +

sizeof(name.sa_family)) < 0)

printf("bind failure %dn", errno);

 196 views

23⟩ What this function connect() does?

Specifying a Remote Socket - connect()

#include <sys/types.h>

#include <sys/socket.h>

int connect(int s, struct sockaddr *name, int namelen)

The bind() call only allows specification of a local address. To specify the remote side of an address connection the connect() call is used. In the call to connect, s is the file descriptor for the socket. name is a pointer to a structure of type sockaddr:

struct sockaddr {

u_short sa_family;

char sa_data[14];

};

As with the bind() system call, name.sa_family should be AF_UNIX. name.sa_data should contain up to 14 bytes of a file name which will be assigned to the socket. namelen gives the actual length of name. A return value of 0 indicates success, while a value of -1 indicates failure with errno describing the error.

A sample code fragment:

struct sockaddr name;

name.sa_family = AF_UNIX;

strcpy(name.sa_data, "/tmp/sock");

if (connect(s, &name, strlen

(name.sa_data) +

sizeof(name.sa_family)) < 0) {

printf("connect failure %dn", errno);

}

 204 views

24⟩ What this function sendto() does?

Sending to a Named Socket - sendto()

int sendto(int s, char *msg, int len, int flags, struct sockaddr *to, int tolen)

This function allows a message msg of length len to be sent on a socket with descriptor s to the socket named by to and tolen, where tolen is the actual length of to. flags will always be zero for our purposes. The number of characters sent is the return value of the function. On error, -1 is returned and errno describes the error.

An example:

struct sockaddr to_name;

to_name.sa_family = AF_UNIX;

strcpy(to_name.sa_data, "/tmp/sock");

if (sendto(s, buf, sizeof(buf),

0, &to_name,

strlen(to_name.sa_data) +

sizeof(to_name.sa_family)) < 0) {

printf("send failuren");

exit(1);

}

 183 views

25⟩ What this function recvfrom() does?

Receiving on a Named Socket - recvfrom()

#include <sys/types.h>

#include <sys/socket.h>

int recvfrom(int s, char *msg, int len, int flags,struct sockaddr *from, int *fromlen)

This function allows a message msg of maximum length len to be read from a socket with descriptor s from the socket named by from and fromlen, where fromlen is the actual length of from. The number of characters actually read from the socket is the return value of the function. On error, -1 is returned and errno describes the error. flags may be 0, or may specify MSG_PEEK to examine a message without actually receiving it from the queue.

If no message is available to be read, the process will suspend waiting for one unless the socket is set to nonblocking mode (via an ioctl call).

The system I/O call read() can also be used to read data from a socket.

 197 views

26⟩ How to disposing of a Socket?

Code Sample: How to disposing of a Socket

#include <stdio.h>

void close(int s).

/* The I/O call close() will close the socket

descriptor s just as it closes

any open file descriptor.

Example - sendto() and recvfrom()

*/

/* receiver */

#include <sys/types.h>

#include <sys/socket.h>

struct sockaddr myname;

struct sockaddr from_name;

char buf[80];

main()

{

int sock;

int fromlen, cnt;

sock = socket(AF_UNIX, SOCK_DGRAM, 0);

if (sock < 0) {

printf("socket failure %dn", errno);

exit(1);

}

myname.sa_family = AF_UNIX;

strcpy(myname.sa_data, "/tmp/tsck");

if (bind(sock, &myname,

strlen(myname.sa_data) +

sizeof(name.sa_family)) < 0) {

printf("bind failure %dn", errno);

exit(1);

}

cnt = recvfrom(sock, buf, sizeof(buf),

0, &from_name, &fromlen);

if (cnt < 0) {

printf("recvfrom failure %dn", errno);

exit(1);

}

buf[cnt] = ''; /* assure null byte */

from_name.sa_data[fromlen] = '';

printf("'%s' received from %sn",

buf, from_name.sa_data);

}

/* sender */

#include <sys/types.h>

#include <sys/socket.h>

char buf[80];

struct sockaddr to_name;

main()

{

int sock;

sock = socket(AF_UNIX, SOCK_DGRAM, 0);

if (sock < 0) {

printf("socket failure %dn", errno);

exit(1);

}

to_name.sa_family = AF_UNIX;

strcpy(to_name.sa_data, "/tmp/tsck");

strcpy(buf, "test data line");

cnt = sendto(sock, buf, strlen(buf),

0, &to_name,

strlen(to_name.sa_data) +

sizeof(to_name.sa_family));

if (cnt < 0) {

printf("sendto failure %dn", errno);

exit(1);

}

}

 179 views

27⟩ How Sockets can be used to write client-server applications using a connection-oriented client-server technique?

Sockets can be used to write client-server applications using a connection-oriented client-server technique. Some characteristics of this technique include:

* The server can handle multiple client requests for connection and service.

* The server responds to any one client's request independently of all other clients.

* A client knows how to establish a connection with the server.

The client-server connection, when established, remains in existence until either the client or the server explicitly breaks it, much like a trouble-free telephone call. The socket used for this connection is called a connection-oriented socket.

The socket type is specified as SOCK_STREAM. As a result, the process receiving a message processes that message by the following rules:

* The data transmitted has no boundaries.

* All bytes in a received message must be read before the next message can be processed.

* Bytes in a received message can be read in a loop program control structure since no data bytes are discarded.

* The server will usually fork() a child process upon establishment of a client connection.

* This child server process is designed to communicate with exactly one client process.

* The child server process performs the requested service for its connected client.

* The child server process terminates when the service request has been completed.

Functions listen() and accept() enable the server to listen for service requests. read() and write() may be used by client and server to send/receive messages; send() and recv() may also be used.

 209 views

28⟩ How to make a Socket a Listen-only Connection Endpoint - listen()?

/*

Code Sample: Make a Socket a Listen-only

Connection Endpoint - listen()

by GlobalGuideline.com

*/

#include <sys/types.h>

#include <sys/socket.h>

int listen(int s, int backlog)

/*

listen establishes the socket as a passive

endpoint of a connection. It does not

suspend process execution.

*/

/*

No messages can be sent through this socket.

Incoming messages can be received.

*/

/*

s is the file descriptor associated with

the socket created using the socket() system

call. backlog is the size of the queue

of waiting requests while the server is busy

with a service request. The current

system-imposed maximum value is 5.

*/

/*

0 is returned on success, -1 on error

with errno indicating the problem.

*/

Example:

#include <sys/types.h>

#include <sys/socket.h>

int sockfd; /* socket file descriptor */

if(listen(sockfd, 5) < 0)

printf ("listen error %dn", errno);

 168 views

29⟩ Explain Connection Establishment by Server - accept()?

#include <sys/types.h>

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *name,

int *namelen)

The accept() call establishes a client-server connection on the server side. (The client requests the connection using the connect() system call.) The server must have created the socket using socket(), given the socket a name using bind(), and established a listen queue using listen().

sockfd is the socket file descriptor returned from the socket() system call. name is a pointer to a structure of type sockaddr as described above

struct sockaddr {

u_short sa_family;

char sa_data[14];

};

Upon successful return from accept(), this structure will contain the protocol address of the client's socket. The data area pointed to by namelen should be initialized to the actual length of name. Upon successful return from accept, the data area pointed to by namelen will contain the actual length of the protocol address of the client's socket.

If successful, accept() creates a new socket of the same family, type, and protocol as sockfd. The file descriptor for this new socket is the return value of accept(). This new socket is used for all communications with the client.

If there is no client connection request waiting, accept() will block until a client request is queued.

accept() will fail mainly if sockfd is not a file descriptor for a socket or if the socket type is not SOCK_STREAM. In this case, accept() returns the value -1 and errno describes the problem.

 180 views

30⟩ Explain Data Transfer over Connected Sockets - send() and recv()?

Two additional data transfer library calls, namely send() and recv(), are available if the sockets are connected. They correspond very closely to the read() and write() functions used for I/O on ordinary file descriptors.

#include <sys/types.h>

#include <sys/socket.h>

int send(int sd, char *buf, int len, int flags)

int recv(int sd, char * buf, int len, int flags)

In both cases, sd is the socket descriptor. For send(), buf points to a buffer containing the data to be sent, len is the length of the data and flags will usually be 0. The return value is the number of bytes sent if successful. If not successful, -1 is returned and errno describes the error.

For recv(), buf points to a data area into which the received data is copied, len is the size of this data area in bytes, and flags is usually either 0 or set to MSG_PEEK if the received data is to be retained in the system after it is received. The return value is the number of bytes received if successful. If not successful, -1 is returned and errno describes the error.

 162 views

31⟩ Explain with a Connection-Oriented Example - listen(), accept()?

/* Generic program structure for establishing

connection-oriented client-server environment.

*/

/* server program */

#include <stdio.h>

#include <errno.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/socket.h>

struct sockaddr myname;

char buf[80];

main()

{

int sock, new_sd, adrlen, cnt;

sock = socket(AF_UNIX, SOCK_STREAM, 0);

if (sock < 0) {

printf("server socket failure %dn", errno);

perror("server: ");

exit(1);

}

myname.sa_family = AF_UNIX;

strcpy(myname.sa_data, "/tmp/billb");

adrlen = strlen(myname.sa_data) +

sizeof(myname.sa_family);

unlink("/tmp/billb"); /* defensive programming */

if (bind(sock, &myname, adrlen) < 0) {

printf("server bind failure %dn", errno);

perror("server: ");

exit(1);

}

if (listen(sock, 5) < 0 {

printf("server listen failure %dn", errno);

perror("server: ");

exit(1);

}

/* Ignore child process termination. */

signal (SIGCHLD, SIG_IGN);

/* Place the server in an infinite loop, waiting

on connection requests to come from clients.

In practice, there would need to be a clean

way to terminate this process, but for now it

will simply stay resident until terminated by

the starting terminal or the super-user. */

while (1) {

if (new_sd = accept(sock,

&myname, &adrlen)) < 0 {

printf("server accept failure %dn", errno);

perror("server: ");

exit(1);

}

/* Create child server process. Parent does no

further processing -- it loops back to wait

for another connection request. */

printf("Socket address in server %d is %x, %sn",

getpid(), myname.sa_data, myname.sa_data);

if (fork() == 0) { /* child process */

close (sock); /* child does not need it */

/* . . . . . */

cnt = read(new_sd, buf, strlen(buf));

printf ("Server with pid %d got message %sn",

getpid(), buf);

strcpy (buf, "Message to client");

cnt = write(new_sd, buf, strlen(buf));

printf("Socket address in server %d is %x, %sn",

getpid(), myname.sa_data, myname.sa_data);

/* . . . . . */

close (new_sd); /* close prior to exiting */

exit(0);

} /* closing bracket for if (fork() ... ) */

} /* closing bracket for while (1) ... ) */

} /* closing bracket for main procedure */

/* client program */

#include <stdio.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/socket.h>

char buf[80];

struct sockaddr myname;

main()

{

int sock, adrlen, cnt;

sock = socket(AF_UNIX, SOCK_STREAM, 0);

if (sock < 0) {

printf("client socket failure %dn", errno);

perror("client: ");

exit(1);

}

myname.sa_family = AF_UNIX;

strcpy(myname.sa_data, "/tmp/billb");

adrlen = strlen(myname.sa_data) +

sizeof(myname.sa_family);

if (connect( sock, &myname, adrlen) < 0) {

printf("client connect failure %dn", errno);

perror("client: ");

exit(1);

}

/* . . . . . */

strcpy(buf, "Message sent to server");

cnt = write(sock, buf, strlen(buf));

cnt = read(sock, buf, strlen(buf));

printf("Client with pid %d got message %sn",

getpid(), buf);

printf("Socket address in server %d is %x, %sn",

getpid(), myname.sa_data, myname.sa_data);

/* . . . . . */

exit(0);

}

 173 views

32⟩ What is the IP Address?

The IP host address, or more commonly just IP address, is used to identify hosts connected to the Internet. IP stands for Internet Protocol and refers to the Internet Layer of the overall network architecture of the Internet. An IP address is a 32-bit quantity interpreted as 4 8-bit numbers or octets. Each IP address uniquely identifies the participating user network, the host on the network, and the class of the user network.

An IP address is usually written in a dotted-decimal notation of the form N1.N2.N3.N4, where each Ni is a decimal number between 0 and 255 decimal (00 through ff hexadecimal). Addresses are controlled and assigned by the Internet Network Information Center at SRI International. There are currently 5 defined classes of networks, called A, B, C, D and E; classes A, B and C are available to users. Each interface on a host system connected to the Internet must have its own IP address.

 169 views

33⟩ What is the /etc/hosts File?

The correspondence between host names and IP addresses is maintained in a file called hosts in the (top-level) directory /etc. On most systems, any user can read this file. (A word of caution: on many systems, printing this file may be injurious to local paper supply!!)

Entries in this file look like the following:

127.0.0.1 localhost

192.217.44.208 snoopy beagle hound metlife

153.110.34.18 bugs wabbit wascal

153.110.34.19 elmer

153.110.34.20 sam

Note that more than one name may be associated with a given IP address. This file is used when converting from IP address to host name and vice versa.

 168 views

34⟩ What is Network Host Names?

Using IP addresses to access hosts on a network is fine for the IP software. Most people are more comfortable with names, and procedures for both proper name construction and translation of these names into IP addresses has been in existence for some time. The most commonly used is the Domain Name System (DNS), occasionally but inaccurately referred to as the Domain Name Service. Naming in DNS is done hierarchically, that is, in a tree-structure format, much like the UNIX file system naming. The top two levels are controlled by the Internet Network Information Center (NIC) at SRI International.

At the top of the domain are two-letter country designators and three-letter (usually) general category designators within the USA. Some examples are:

* fr -- France

* gov -- government

* nz -- New Zealand

* com -- commercial business

* us -- USA

* edu -- educational institution

* uk -- United Kingdom

* mil -- military

The next level usually identifies the institution. For example:

* ibm -- IBM Corporation

* utdallas -- UT-D

* ti -- Texas Instruments (TI)

* nasa -- NASA

DNS and other software help in maintenance of these naming conventions and in the translation of host names to IP addresses and vice versa.

 171 views

35⟩ How to Selecte a Service Port?

The protocol specifications of the protocols used in the AF_INET domain require specification of a port. The port number is used to determine which process on the remote machine to talk to.

Certain network services have been assigned Well Known Ports. The port assignments to network services can be found in the file /etc/services. Selection of a Well Known Port involves searching this file and is done with the following functions:

#include <netdb.h>

struct servent *getservbyname(char *name,char *proto)

struct servent *getservbyport(int port,char *proto)

The two options for proto in each call are tcp for stream oriented communications, and udp for datagram oriented communications. port is the (known) port number when the service name is requested, while name is the character string containing the service name when the port number is requested.

The return value for each function is a pointer to a structure with the following form:

struct servent {

char *s_name; /* official name of service */

char **s_aliases; /* alias service name list */

long s_port; /* port service resides at */

char *s_proto; /* protocol to use */

};

If a program does not need to communicate with a Well Known Port it is possible to choose an unused port for use by a program.

 166 views

36⟩ How to Put a Host Program Address Together?

Once a host address and port number are known then the complete process address must be put together in a form that may be used by the system calls already covered. The structures set up to allow this follow:

#include <netinet/in.h>

/*

* Internet address

(a structure for historical reasons)

*/

struct in_addr {

union {

struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;

struct { u_short s_w1,s_w2; } S_un_w;

u_long S_addr;

} S_un;

#define s_addr S_un.S_addr

/* can be used for most tcp & ip code */

};

/*

* Socket address, internet style.

*/

struct sockaddr_in {

short sin_family;

u_short sin_port;

struct in_addr sin_addr;

char sin_zero[8];

};

Filling in the fields for sockaddr_in will produce an Internet version of a socket address.

 175 views

37⟩ How to finding a Machine Address?

Finding an address that can be used to connect to a remote machine is done with either of the following commands:

#include <netdb.h>

struct hostent *gethostbyname(char *name)

struct hostent *gethostbyaddr(char *addr,

int len, int type)

name contains the host name for which the IP address is needed. addr points to a structure of type in_addr and len is the size in bytes of this structure. In this discussion type is always AF_INET since the discussion is limited to use of IP addresses on the Internet.

Both calls return a pointer to a host entry structure.

This structure has the following form:

struct hostent {

char *h_name; /*official name of host*/

char **h_aliases; /* alias list */

int h_addrtype; /* address type */

int h_length; /* length of address */

char **h_addr_list;

/* list of addresses from name server */

#define h_addr h_addr_list[0]

/* address for backward compatibility */

};

 188 views

38⟩ Explain Network Address Conversion Routines?

Network Address Conversion Routines

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

/* in_addr structure */

unsigned long inet_addr(char *ptr)

char *inet_ntoa(struct in_addr inaddr)

inet_addr() converts a character string in dotted-decimal notation to a 32-bit Internet address. The return value is not consistent, unfortunately. The correct return should be a pointer to a structure of type in_addr but many systems, following an older convention, return only the internal representation of the dotted-decimal notation. The man pages will clarify the situation for the host system on which the function is used.

inet_ntoa() expects a structure of type in_addr as a parameter (note that the structure itself is passed, not a pointer) and returns a pointer to a character string containing the dotted-decimal representation of the Internet address.

 161 views

39⟩ Explain Routines for converting data between a hosts internal representation and Network Byte Order?

Routines for converting data between a host's internal representation and Network Byte Order are:

#include <sys/types.h>

#include <netinet/in.h>

u_long htonl(u_long hostlong);

u_short htons(u_short hostshort);

u_long ntohl(u_long netlong);

u_short ntohs(u_short netshort);

These functions are macros and result in the insertion of conversion source code into the calling program. On little-endian machines the code will change the values around to network byte order. On big-endian machines no code is inserted since none is needed; the functions are defined as null.

 189 views

40⟩ Socket Programming in C using TCP with Code?

To compile :

* linux : gcc -Wall -o foo foo.c

* solaris :gcc -Wall -o foo foo.c -lsocket -lnsl

1. TCP

* TCP server : simple TCP server

that prints received messages.

source : tcpServer.c

usage : ./tcpServer

* TCP client : simple TCP client

that sends data to server.

source : tcpClient.c

usage :./tcpClient server data1...dataN

/*********** tcpserver.c **********/

by : prasad

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <stdio.h>

#include <unistd.h>/*close*/

#define SUCCESS 0

#define ERROR 1

#define END_LINE 0x0

#define SERVER_PORT 1500

#define MAX_MSG 100

/* function readline */

int read_line();

int main (int argc, char *argv[])

{

int sd, newSd, cliLen;

struct sockaddr_in cliAddr, servAddr;

char line[MAX_MSG];

/* create socket */

sd = socket(AF_INET, SOCK_STREAM, 0);

if(sd<0) {

perror("cannot open socket ");

return ERROR;

}

/* bind server port */

servAddr.sin_family = AF_INET;

servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

servAddr.sin_port = htons(SERVER_PORT);

if(bind(sd, (struct sockaddr *) &servAddr,

sizeof(servAddr))<0) {

perror("cannot bind port ");

return ERROR;

}

listen(sd,5);

while(1) {

printf("%s: waiting for data on port TCP %un"

,argv[0],SERVER_PORT);

cliLen = sizeof(cliAddr);

newSd = accept(sd, (struct sockaddr *)

&cliAddr, &cliLen);

if(newSd<0) {

perror("cannot accept connection ");

return ERROR;

}

/* init line */

memset(line,0x0,MAX_MSG);

/* receive segments */

while(read_line(newSd,line)!=ERROR) {

printf("%s: received from %s:TCP%d :

%sn", argv[0],

inet_ntoa(cliAddr.sin_addr),

ntohs(cliAddr.sin_port), line);

/* init line */

memset(line,0x0,MAX_MSG);

} /* while(read_line) */

} /* while (1) */

}

/* WARNING WARNING WARNING WARNING WARNING

WARNING WARNING */

/* this function is experimental..

I don't know yet if it works */

/* correctly or not. Use Steven's

readline() function to have */

/* something robust. */

/* WARNING WARNING WARNING

WARNING WARNING WARNING WARNING */

/* rcv_line is my function readline().

Data is read from the socket when */

/* needed, but not byte after bytes.

All the received data is read.

*/

/* This means only one call to recv(),

instead of one call for

*/

/* each received byte.

*/

/* You can set END_CHAR to whatever

means endofline for you. (0x0A is n)*/

/* read_lin returns the number of

bytes returned in line_to_return

*/

int read_line(int newSd, char *line_to_return)

{

static int rcv_ptr=0;

static char rcv_msg[MAX_MSG];

static int n;

int offset;

offset=0;

while(1) {

if(rcv_ptr==0) {

/* read data from socket */

memset(rcv_msg,0x0,MAX_MSG);

/* init buffer */

n = recv(newSd, rcv_msg, MAX_MSG, 0);

/* wait for data */

if (n<0) {

perror(" cannot receive data ");

return ERROR;

} else if (n==0) {

printf(" connection closed by clientn");

close(newSd);

return ERROR;

}

}

/* if new data read on socket */

/* OR */

/* if another line is still in buffer */

/* copy line into 'line_to_return' */

while(*(rcv_msg+rcv_ptr)!=

END_LINE && rcv_ptr<n) {

memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);

offset++;

rcv_ptr++;

}

/*end of line + end of buffer =<returnline*/

if(rcv_ptr==n-1) {

/* set last byte to END_LINE */

*(line_to_return+offset)=END_LINE;

rcv_ptr=0;

return ++offset;

}

/* end of line but still some data in

buffer =>return line */

if(rcv_ptr <n-1) {

/* set last byte to END_LINE */

*(line_to_return+offset)=END_LINE;

rcv_ptr++;

return ++offset;

}

/* end of buffer but line is not ended =>*/

/* wait for more data to arrive on socket */

if(rcv_ptr == n) {

rcv_ptr = 0;

}

} /* while */

}

/******* tcpclient.c *******/

/* tcpClient.c */

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <stdio.h>

#include <unistd.h> /*close*/

#define SERVER_PORT 1500

#define MAX_MSG 100

int main (int argc, char *argv[]) {

int sd, rc, i;

struct sockaddr_in localAddr, servAddr;

struct hostent *h;

if(argc < 3) {

printf("usage: %s <server> <data1>

<data2> ... <dataN>n",argv[0]);

exit(1);

}

h = gethostbyname(argv[1]);

if(h==NULL) {

printf("%s: unknown host '%s'n"

,argv[0],argv[1]);

exit(1);

}

servAddr.sin_family = h-<h_addrtype;

memcpy((char *) &servAddr.sin_addr.s_addr,

h-<h_addr_list[0],h-<h_length);

servAddr.sin_port = htons(SERVER_PORT);

/* create socket */

sd = socket(AF_INET, SOCK_STREAM, 0);

if(sd<0) {

perror("cannot open socket ");

exit(1);

}

/* bind any port number */

localAddr.sin_family = AF_INET;

localAddr.sin_addr.s_addr =

htonl(INADDR_ANY);

localAddr.sin_port = htons(0);

rc = bind(sd, (struct sockaddr *) &

localAddr, sizeof(localAddr));

if(rc<0) {

printf("%s: cannot bind port TCP %un",

argv[0],SERVER_PORT);

perror("error ");

exit(1);

}

/* connect to server */

rc = connect(sd, (struct sockaddr *)

&servAddr, sizeof(servAddr));

if(rc<0) {

perror("cannot connect ");

exit(1);

}

for(i=2;i<argc;i++) {

rc = send(sd, argv[i], strlen(argv[i])

+ 1, 0);

if(rc<0) {

perror("cannot send data ");

close(sd);

exit(1);

}

printf("%s: data%u sent (%s)n",

argv[0],i-1,argv[i]);

}

return 0;

}

 177 views