Mostly Asked Socket Programming Interview Preparation Guide
Download PDF

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:

Table of Contents:

Mostly Asked  Socket Programming Job Interview Questions and Answers
Mostly Asked Socket Programming Job Interview Questions and Answers

1 :: What is Server Applications?

Server Applications:

A system offers a service by having an application running that is listening at the service port and willing to accept a connection from a client. If there is no application listening at the service port then the machine doesn't offer that service.

The SMTP service is provided by an application listening on port 25. On Unix systems this is usually the sendmail(1M) application which is started at boot time.

[2:20pm julian] ps -agx | grep sendmail
419 ? SW 0:03 /usr/lib/sendmail -bd -q15m
18438 ? IW 0:01 /usr/lib/sendmail -bd -q15m

[2:28pm julian] netstat -a | grep smtp
tcp 0 0 julian.3155 acad3.alask.smtp SYN_SENT
tcp 0 0 *.smtp *.* LISTEN

In the example we have a process listening to the smtp port (for inbound mail) and another process talking to the smtp port on acad3.alaska.edu (ie. sending mail to that system).

2 :: What is Client Connect?

A client application creates a socket(3N)
and then issues a connect(3N)
to a service specified
in a sockaddr_in structure:

int tcpopen(host,service)
char *service, *host;
{ int unit;
struct sockaddr_in sin;
struct servent *sp;
struct hostent *hp;

if ((sp=getservbyname(service,"tcp")) == NULL)
then error...
if ((hp=gethostbyname(host)) == NULL)
then Ierror...
bzero((char *)&sin, sizeof(sin))
etc...
if ((unit=socket(AF_INET,SOCK_STREAM,0)) < 0)
then error...
if (connect(unit,&sin,sizeof(sin)) <0)
then error...
return(unit);
}

The result returned is a file descriptor which is connected to a server process. A communications channel on which one can conduct an application specific protocol.

Client Communication:

Having connected a socket to a server to establish a file descriptor communication is with the usual Unix I/O calls. You have Inter Process Communication (or IPC) to a server.

Many programmers turn file descriptors into stdio(3S) streams so they can use fputs, fgets, fprintf, etc. -- use fdopen(3S).

main(argc,argv)
int argc;
char *argv[];
{
int unit,i;
char buf[BUFSIZ];
FILE *sockin,*sockout;

if ((unit=tcpopen(WHOHOST,WHOPORT))
< 0) then error...
sockin=fdopen(unit,"r");
sockout=fdopen(unit,"w");
etc...
fprintf(sockout,"%sn",argv[i]);
etc...
while (fgets(buf,BUFSIZ,sockin)) etc...

Stdio Buffers:

Stdio streams have powerful manipulation tools (eg. fscanf is amazing). But beware, streams are buffered! This means a well placed fflush(3S) is often required to flush a buffer to the peer.

fprintf(sockout,"%sn",argv[i]);
fflush(sockout);

while (fgets(buf,BUFSIZ,sockin)) etc...

Many client/server protocols are client driven -- the client sends a command and expects an answer. The server won't see the command if the client doesn't flush the output. Likewise, the client won't see the answer if the server doesn't flush it's output.

Watch out for client and server blocking -- both waiting for input from the other.

3 :: What is File Descriptors and Sockets?

File Descriptors:

File Descriptors are the fundamental I/O object. You read(2) and write(2) to file descriptors.

int cc, fd, nbytes;
char *buf;

cc = read(fd, buf, nbytes);
cc = write(fd, buf, nbytes)

The read attempts to read nbytes of data from the object referenced by the file descriptor fd into the buffer pointed to by buf. The write does a write to the file descriptor from the buffer. Unix I/O is a byte stream.

File descriptors are numbers used for I/O. Usually the result of open(2) and creat(2) calls.

All Unix applications run with stdin as file descriptor 0, stdout as file descriptor 1, and stderr as file descriptior 3. But stdin is a FILE (see stdio(3S)) not a file descriptor. If you want a stdio FILE on a file descriptor use fdopen(3S).

Sockets:

A Socket is a Unix file descriptor created by the socket(3N) call -- you don't open(2) or creat(2) a socket. By way of comparison pipe(2) creates file descriptors too -- you might be familiar with pipes which predate sockets in the development of the Unix system.

int s, domain, type, protocol;
s = socket(domain, type, protocol);
etc...
cc = read(s, buf, nbytes);

The domain parameter specifies a communications domain (or address family). For IP use AF_INET but note that socket.h lists all sorts of address families. This is to inform the system how an address should be understood -- on different networks, like AF_DECnet, addressing may be longer than the four octets of an IP number. We're only concerned with IP and the AF_INET address family.

The type parameter specifies the semantics of communication (sometimes know as a specification of quality of services). For TCP/IP use SOCK_STREAM (for UDP/IP use SOCK_DGRAM). Note that any address family might support those service types. See socket.h for a list of service types that might be supported.

A SOCK_STREAM is a sequenced, reliable, two-way connection based byte stream. If a data cannot be successfully transmitted within a reasonable length of time the connection is considered broken and I/O calls will indicate an error.

The protocol specifies a particular protocol to be used with the socket -- for TCP/IP use 0. Actually there's another programmers interface getprotobyname(3N) that provides translates protocol names to numbers. It's an interface to the data found in /etc/protocols -- compare with the translation of service names to port numbers discussed above.

4 :: What is Socket Addressing?

A Socket Address is a host.port pair (communication is between host.port pairs -- one on the server, the other on the client). We know how to determine host numbers and service numbers so we're well on our way to filling out a structure were we specify those numbers. The structure is sockaddr_in, which has the address family is AF_INET as in this fragment:

int tcpopen(host,service)
char *service, *host;
{ int unit;
struct sockaddr_in sin;
struct servent *sp;
struct hostent *hp;
etc...
if ((sp=getservbyname(service,"tcp"))
== NULL) then error...
if ((hp=gethostbyname(host)) == NULL)
then error...

bzero((char *)&sin, sizeof(sin));
sin.sin_family=AF_INET;
bcopy(hp->h_addr,(char *)&sin.sin_addr,
hp->h_length);
sin.sin_port=sp->s_port;
etc...

The code fragment is filling in the IP address type AF_INET, port number and IP address in the Socket Address structure -- the address of the remote host.port where we want to connect to find a service.

There's a generic Socket Address structure, a sockaddr, used for communication in arbitrary domains. It has an address family field and an address (or data) field:

/* from: /usr/include/sys/socket.h */


struct sockaddr {
u_short sa_family; /*address family */
char sa_data[14];/*max 14 byte addr*/
};


The sockaddr_in structure is for
Internet Socket Addresses
address family AF_INET). An instance
of the generic socket address.

/* from: /usr/include/netinet/in.h */
struct sockaddr_in {
short sin_family; /* AF_INET */
u_short sin_port; /* service port */
struct in_addr sin_addr; /*host number */
char sin_zero[8]; /* not used */
};


The family defines the interpretation of the data. In other domains addressing will be different -- services in the UNIX domain are names (eg. /dev/printer). In the sockaddr_in structure we've got fields to specify a port and a host IP number (and 8 octets that aren't used at all!). That structure specifies one end of an IPC connection. Creating that structure and filling in the right numbers has been pretty easy so far.

5 :: How do we get a process bound behind a port?

Server Bind:

A Server uses bind(3N) to establish the local host.port assignment -- ie. so it is the process behind that port. That's really only required for servers -- applications which accept(3N) connections to provide a service.

struct servent *sp;
struct sockaddr_in sin;

if ((sp=getservbyname(service,"tcp")) == NULL) then error...

sin.sin_family=AF_INET;
sin.sin_port=sp->s_port;
sin.sin_addr.s_addr=htonl(INADDR_ANY);

if ((s=socket(AF_INET,SOCK_STREAM,0)) < 0) then error...
if (bind(s, &sin, sizeof(sin)) < 0) then error...

htonl(3N) converts a long to the right sequence (given different byte ordering on different machines). The IP address INADDR_ANY means all interfaces. You could, if you wanted, provide a service only on some interfaces -- eg. if you only provided the service on the loopback interface (127.0.0.1) then the service would only be available to clients on the same system.

What this code fragment does is specify a local interface and port (into the sin structure). The process is bound to that port -- it's now the process behind the local port.

Client applications usually aren't concerned about the local host.port assignment (the connect(3N) does a bind o some random but unused local port on the right interface). But rcp(1) and related programs (like rlogin(1) and rsh(1)) do connect from reserved port numbers.

For example, the version of tcpopen.c used in the Passwdd/Passwd -- An authentication Daemon/Client. There's an instance where a client application connects from a reserved port.

Listen and Accept:

To accept connections, a socket is created with socket(3N), it's bound to a service port with bind(3N), a queue for incoming connections is specified with listen(3N) and then the connections are accepted with accept(3N) as in this fragment:

struct servent *sp;
struct sockaddr_in sin,from;

if ((sp=getservbyname(service,"tcp")) == NULL)
then error...
sin.sin_family=etc...
if ((s=socket(AF_INET,SOCK_STREAM,0)) < 0)
then error...
if (bind(s, &sin, sizeof(sin)) < 0)
then error...
if (listen(s,QUELEN) < 0) then error...
for (;;) {
if ((g=accept(f,&from,&len)) < 0)
then error...
if (!fork()) {
child handles request...
...and exits
exit(0);
}
close(g); /* parent releases file */
}


This is the programming schema used by utilities like sendmail(1M) and others -- they create their socket and listen for connections. When connections are made, the process forks off a child to handle that service request and the parent process continues to listen for and accept further service requests.

6 :: What is Inetd Services?

Not all services are started at boot time by running a server application. Eg. you won't usually see a process running for the finger service like you do for the smtp service. Many are handled by the InterNet Daemon inetd(1M). This is a generic service configured by the file inetd.conf(4).

[2:35pm julian] page /etc/inetd.conf
# $Author: reggers $
# $Date: 1997/05/02 20:17:16 $
#
# Internet server configuration database
ftp stream tcp nowait root /usr/etc/ftpd ftpd
telnet stream tcp nowait root /usr/etc/telnetd telnetd
shell stream tcp nowait root /usr/etc/rshd rshd
login stream tcp nowait root /usr/etc/rlogind rlogind
exec stream tcp nowait root /usr/etc/rexecd rexecd
uucpd stream tcp nowait root /usr/etc/uucpd uucpd
finger stream tcp nowait nobody /usr/etc/fingerd fingerd
etc...
whois stream tcp nowait nobody /usr/lib/whois/whoisd whoisd
etc...


Inetd Comments:

For each service listed in /etc/inetd.conf the inetd(1M) process, and that is a process is started at boot time, executes the socket(3N), bind(3N), listen(3N) and accept(3N) calls as discussed above. Inetd also handles many of the daemon issues (signal handling, set process group and controlling tty) which we've studiously avoided.

The inetd(1M) process spawns the appropriate server application (with fork(2) and exec(2)) when a client connects to the service port. The daemon continues to listen for further connections to the service while the spawned child process handles the request which just came in.

The server application (ie. the child spawned by inetd(1M)) is started with stdin and stdout connected to the remote host.port of the client process which made the connection. Any input/output by the server appliation on stdin/stdout are sent/received by the client application. You have Inter Process Communication (or IPC)!

This means, any application written to use stdin/stdout can be a server application. Writing a server application should therefore be fairly simple.

7 :: What is Whois Daemon?

Simple WHOIS Daemon, provides the standard Internet whois directory service It is much simpler to setup and administrator than the other whois daemons available, such as RIPE whois or the original SRC whois. This is because it uses a flat-text file, /etc/swhoisd.conf, instead of a complex database. This whois server is recommended only for small databases (preferably under 100 records and no more than 1000).

8 :: How to run the WHOIS Daemon?

You can run the whois daemon (on the server) to
see what it does:

[3:27pm julian] echo reggers | /usr/lib/whois/whoisd
There were 1 matches on your request.

Full Name: Quinton, Reg
Department: Info Tech Svcs
Room: NSC 214
Phone: 679-2111x(6026)
Index Key: 481800
Machine Address: reggers@julian.uuu.com
Directory Addresses: reg.quinton@uuu.com
: r.quinton@uuu.com
: reggers@uuu.com
: quinton@uuu.com

For more information try 'whois help'.

The program is command driven -- you give a command (or query string) on stdin, it produces results on stdout, and exits.

Connecting to the Server:

You can make a telnet(1) connection to
the whois service on the server.

[3:47pm julian] telnet julian whois
Trying 129.100.2.12 ... Connected to julian.
Escape character is '^]'.
reggers .... my command input
There were 1 matches on your request.

Full Name: Quinton, Reg
Department: Info Tech Svcs
Room: NSC 214
Phone: 679-2111x(6026)
Index Key: 481800
Machine Address: reggers@julian.uuu.com
Directory Addresses: reg.quinton@uuu.com
: r.quinton@uuu.com
: reggers@uuu.com
: quinton@uuu.com

For more information try 'whois help'.
Connection closed by foreign host.

9 :: What is Whois Client?

Whois Client: This is whois, a very simple and generic whois client. This client, unlike the classic whois client, does not check for supported flags at the client side, except for -h (whois host) and -p (whois port).

The whois(1) client makes a TCP/IP connection
to the server and conducts the kind of protocol
that you would type if you where to make
a connection by hand:


[7:30am julian] whois reggers
There were 1 matches on your request.

Full Name: Quinton, Reg
Department: Info Tech Svcs
Room: NSC 214
Phone: 679-2111x(6026)
Index Key: 481800
Machine Address: reggers@julian.uuu.com
Directory Addresses: reg.quinton@uuu.com
: r.quinton@uuu.com
: reggers@uuu.com
: quinton@uuu.com

For more information try 'whois help'.

The client sends the command "reggers", the server sends back the answer and the client displays the answer received to the user. When the server is finished the connection is closed.

Sample code: whois(1) client


sub tcpopen {
use Socket; # need socket interface
my($server, $service) = @_;# args to this function
my($proto, $port, $iaddr); # local variables
my($handle)="$server::$service";
# localized obscure handle

die("550:Cannot getprotobyname('tcp')rn")
unless ($proto = getprotobyname('tcp'));

die("550:Cannot getservbyname($service)rn")
unless ($port = getservbyname($service, 'tcp'));

die("550:Cannot gethostbyname($server)rn")
unless ($iaddr = gethostbyname($server));

die("550:Cannot create socketrn")
unless socket($handle, PF_INET, SOCK_STREAM, $proto);

die("550:Cannot connect($service://$server)rn")
unless connect($handle, sockaddr_in($port, $iaddr));

# unbuffered I/O to that service

select($handle); $| = 1; select(STDOUT); $| = 1;

return($handle);
}

10 :: What are basic functions of network programming interface?

Most operating systems provide precompiled programs that communicate across a network. Common examples into the TCP/IP world are web clients(browsers) and web servers, and the FTP and TELNET clients and servers.

A socket is an endpoint used by a process for bi-directional communication with a socket associated with another process. Sockets, introduced in Berkeley Unix, are a basic mechanism for IPC on a computer system, or on different computer systems connected by local or wide area networks(resource 2). To understand some structs into this subject is necessary a deeper knowledge about the operating system and his networking protocols. This subject can be used as either beginners programmers or as a reference for experienced programmers.

The Socket Function
Most network applications can be divided into two pieces: a client and a server.

Creating a socket
#include <sys/types.h>
#include <sys/socket.h>

When you create a socket there are three main parameters that you have to specify:

* the domain
* the type
* the protocol

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

The Domain parameter specifies a communications domain within which communication will take place, in the example the domain parameter was AF_INET, that specify the ARPA Internet Protocols The Type parameter specifies the semantics of communication, in the mini chat used the Stream socket type(SOCK_STREAM), because it offers a bi-directional, reliable, two-way connection based byte stream(resource 2). Finally the protocol type, since used a Stream Socket type, must use a protocol that provide a connection-oriented protocol, like IP, decide to use IP in our protocol Type, and we saw in /etc/protocols the number of ip, 0. So the function now is:

s = socket(AF_INET , SOCK_STREAM , 0)

where 's' is the file descriptor returned by the socket function.

Since the mini chat is divided in two parts it will be divided the explanation in the server, the client and the both, showing the basic differences between them, as see next.

The Mini-chat Server structure
Binding a socket to a port and waiting for the connections

Like all services in a Network TCP/IP based, the sockets are always associated with a port, like Telnet is associated to Port 23, FTP to 21... In the Server, to do the same thing, bind some port to be prepared to listening for connections ( that is the basic difference between Client and Server), Listing 2. Bind is used to specify for a socket the protocol port number where it will be waiting for messages.

So there is a question, which port could be new service? Since the system pre-defined a lot of ports between 1 and 7000 ( /etc/services ) choose the port number 15000.

The function of bind is:


int bind(int s, struct sockaddr *addr, int addrlen)

The struct necessary to make socket works is the struct sockaddr_in address; and the follow lines to say to system the information about the socket.

The type of socket
address.sin_family = AF_INET /* use a internet domain */
The IP used
address.sin_addr.s_addr = INADDR_ANY /*use a specific IP of host*/
The port used
address.sin_port = htons(15000); /* use a specific port number */

And finally bind our port to the socket

bind(create_socket , (struct sockaddr *)&address,sizeof(address));

Now another important phase, prepare a socket to accept messages from clients, the listen function is used on the server in the case of connection oriented communication and also the maximum number of pending connections(resource 3).

listen (create_socket, MAXNUMBER)

where MAXNUMER in the case is 3. And to finish, tell the server to accept a connection, using the accept() function. Accept is used with connection based sockets such as streams.

accept(create_socket,(struct sockaddr *)&address,&addrlen);

As see in Listing 2 The parameters are the socket descriptor of the master socket (create_socket), followed by a sockeaddr_in structure and the size of the structure.(resource 3)

The Mini-chat Client structure


Maybe the biggest difference is that client needs a Connect() function. The connect operation is used on the client side to identify and, possibly, start the connection to the server. The connect syntax is

connect(create_socket,(struct sockaddr *)&address,sizeof(address)) ;

The common structure

A common structure between Client and the Server is the use of the struct hostent as seeing in Listing 1 and 2. The use of the Send and Recv functions are another common codes.

The Send() function is used to send the buffer to the server

send(new_socket,buffer,bufsize,0);

and the Recv() function is used to receive the buffer from the server, look that it is used both in server and client.

recv(new_socket,buffer,bufsize,0);

Since the software of the TCP/IP protocol is inside the operating system, the exactly interface between an application and the TCP/IP protocols depends of the details of the operating system(resource 4). In the case, examine the UNIX BSD socket interface because Linux follow this. The Mini-chat developed here is nothing more than a explain model of a client/server application using sockets in Linux and should be used like a introduction of how easy is to develop applications using sockets. After understand this you can easily start to think about IPC (interprocess Communication), fork, threads(resource 5) and much more. The basic steps to make it work is:

1. Run the server
2. Run the client with the address of the server
By Pedro Paulo Ferreira Bueno and Antonio Pires de Castro Junior

11 :: Explain what is a socket?

A socket is a communications connection point (endpoint) that you can name and address in a network. The processes that use a socket can reside on the same system or on different systems on different networks. Sockets are useful for both stand-alone and network applications.

Sockets commonly are used for client/server interaction. Typical system configuration places the server on one machine, with the clients on other machines. The clients connect to the server, exchange information, and then disconnect.

Socket characteristics:
. A socket is represented by an integer. That integer is called a socket descriptor.
. A socket exists as long as the process maintains an open link to the socket.
. You can name a socket and use it to communicate with other sockets in a communication domain.
. Sockets perform the communication when the server accepts connections from them, or when it exchanges messages with them.
.You can create sockets in pairs.
The connection that a socket provides can be connection-oriented or connectionless.
Connection-oriented communication implies that a connection is established, and a dialog between the programs will follow. The program that provides the service (the server program) establishes the connection. It assigns itself a name that identifies where to obtain that service. The client of the service (the client program) must request the service of the server program. The client does this by connecting to the distinct name that the server program has designated. It is similar to dialing a telephone number (an identifier) and making a connection with another party that is offering a service (for example, a plumber). When the receiver of the call (the server) answers the telephone, the connection is established. The plumber verifies that you have reached the correct party, and the connection remains active as long as both parties require it.
Connectionless communication implies that no connection is established over which a dialog or data transfer can take place. Instead, the server program designates a name that identifies where to reach it (much like a post office box). By sending a letter to a post office box, you cannot be absolutely sure the letter is received. You may have to send another letter to reestablish communication.

12 :: Explain How do sockets work?

A socket has a typical flow of events. In a connection-oriented client-to-server model, the socket on the server process waits for requests from a client. To do this, the server first establishes (binds) an address that clients can use to find the server. When the address is established, the server waits for clients to request a service. The server performs the client’s request and sends the reply back to the client. The two endpoints establish a connection, and bring the client and server together. The client-to-server data exchange takes place when a client connects to the server through a socket.

1. The socket() function creates an endpoint for communications and returns a socket descriptor that represents the endpoint.
2. When an application has a socket descriptor, it can bind a unique name to the socket. Servers must bind a name to be accessible from the network.
3. The listen() function indicates a willingness to accept client connection requests. When a listen() is issued for a socket, that socket cannot actively initiate connection requests. The listen() API is issued after a socket is allocated with a socket() function and the bind() function binds a name to the socket. A listen() function must be issued before an accept() function is issued.
4. The client application uses a connect() function on a stream socket to establish a connection to the server.
5. Servers use stream sockets to accept a client connection request with the accept() function. The server must issue the bind() and listen() functions successfully before it can issue an accept() function to accept an incoming connection request.
6. When a connection is established between stream sockets (between client and server), you can use any of the socket API data transfer functions. Clients and servers have many data transfer functions from which to choose, such as send(), recv(), read(), write(), and others.
7. When a server or client wants to cease operations, it issues a close() function to release any system resources acquired by the socket.

13 :: Overview of Object Serialization

Overview of Object Serialization
Object serialization is a mechanism that is useful in any program that wants to save the state of objects to a file and later read those objects to reconstruct the state of the program, or to send an object over the network using sockets. Serializing a class can be easily done simply by having the class implement the java.io.Serializable interface. This interface is a marker interface. In other words, it does not have any methods that need to be implemented by the class implementing it. It is mainly used to inform the Java virtual machine (JVM) that you want the object to be serialized.

There are two main classes that are used for reading and writing objects to streams: ObjectOutputStream and ObjectInputStream. The ObjectOutputStream provides the writeObject method for writing an object to an output stream, and the ObjectInputStream provides the readObject method for reading the object from an input stream. It is important to note that the objects used with these methods must be serialized. That is, their classes must implement the Serializable interface.

14 :: Shows how to save a Date object to a file?

Code Sample 1: SaveDate.java


import java.io.*;
import java.util.Date;

public class SaveDate {

public static void main(
String argv[]) throws Exception {

FileOutputStream fos =
new FileOutputStream("date.out");

ObjectOutputStream oos =
new ObjectOutputStream(fos);

Date date = new Date();
oos.writeObject(date);
oos.flush();
oos.close();
fos.close();
}
}

15 :: Shows how to read a serialized object and print its information?

Code Sample: ReadDate.java

import java.io.*;
import java.util.Date;

public class ReadDate {

public static void main
(String argv[]) throws Exception

{
FileInputStream fis =
new FileInputStream("date.out");

ObjectInputStream ois =
new ObjectInputStream(fis);

Date date = (Date) ois.readObject();

System.out.println("The date is: "+date);

ois.close();
fis.close();
}
}

In the example above we have worked with an instance of the Date class, which is an existing serialized Java class. The question that may come to mind is: are all existing Java class serialized? The answer is: No. Either because they don't need to be, or it doesn't make sense to serialize some classes. To find out if a class is serializable, use the tool serialver that comes with the JDK. You can either use it from the command line as follows:

c:> serialver java.util.Date
java.util.Date: static final long serialVersionUID = 7523967970034938905L;

(In this example, we are testing if the Date class is serializable. The output here means that the Date class is serializable and it print its version unique identifier.)

Or, alternatively, you can use the GUI-based serialver tool using the command:

c:> serialver -show

This command pops up a window, where you can write the name of the class (including its path) that you want to check.

16 :: How to serialize a custom class?

In this example, we create a custom class, UserInfo which is shown in Code Sample. To make it serializable, it implements the Serializable interface.

Code Sample 3: UserInfo.java

mport java.io.*;
import java.util.*;

public class
UserInfo implements Serializable {
String name = null;

public UserInfo(String name) {
this.name = name;
}

public void printInfo() {
System.out.println("The name is: "+name);
}
}

17 :: How to create a class that creates a instance of the UserInfo class and writes the object to an output stream?

Create a class that creates a instance of the UserInfo class and writes the object to an output stream as shown in Code Sample. The output stream in this example is a file called "name.out". The important thing to note from Code Sample is that the writeObject method can be called any number of times to write any number of objects to the output stream.

Code Sample: SaveInfo.java
import java.io.*;
import java.util.Date;

public class SaveInfo {

public static void main
(String argv[]) throws Exception {
FileOutputStream fos =
new FileOutputStream("name.out");
ObjectOutputStream oos =
new ObjectOutputStream(fos);
// create two objects
UserInfo user1 = new UserInfo("Java Duke");
UserInfo user2 = new UserInfo("Java Blue");
// write the objects to the output stream
oos.writeObject(user1);
oos.writeObject(user2);
oos.flush();
oos.close();
fos.close();
}
}

18 :: How to write a class that reads the objects that have been saved, and invokes a method?

Write a class that reads the objects that have been saved, and invokes a method as shown in Code Sample. Again, as with writeObject, the readObject method can be called any number of times to read any number of objects from the input stream.

Code Sample: ReadInfo.java
import java.io.*;
import java.util.Date;

public class ReadInfo {

public static void main(String argv[]) throws Exception {
FileInputStream fis = new FileInputStream("name.out");
ObjectInputStream ois = new ObjectInputStream(fis);
// read the objects from the input stream (the file name.out)
UserInfo user1 = (UserInfo) ois.readObject();
UserInfo user2 = (UserInfo) ois.readObject();
// invoke a method on the constructed object
user1.printInfo();
user2.printInfo();
ois.close();
fis.close();
}
}

To try out this example, compile the source files: UserInfo.java, SaveInfo.java, and ReadInfo.java. Run SaveInfo, then ReadInfo, and you would see some output similar to this:

The name is: Java Duke
The name is: Java Blue

19 :: Explain A multi-threaded DateServe that listens on port 3000 and waits for requests from clients?

Here A multi-threaded DateServer that listens on port 3000 and waits for requests from clients. Whenever there is a request, the server replies by sending a Date object (over sockets) to the client as shown in Code Sample.

Code Sample: DateServer.java
import java.io.*;
import java.net.*;
import java.util.*;

public class DateServer
extends Thread {

private ServerSocket dateServer;


public static void main
(String argv[]) throws Exception {
new DateServer();
}

public DateServer() throws Exception {
dateServer = new ServerSocket(3000);
System.out.println
("Server listening on port 3000.");
this.start();
}

public void run() {
while(true) {
try {
System.out.println("Waiting for connections.");
Socket client = dateServer.accept();
System.out.println("Accepted a connection
from: "+ client.getInetAddress());
Connect c = new Connect(client);
} catch(Exception e) {}
}
}
}

class Connect extends Thread {
private Socket client = null;
private ObjectInputStream ois = null;
private ObjectOutputStream oos = null;

public Connect() {}

public Connect(Socket clientSocket) {
client = clientSocket;
try {
ois = new ObjectInputStream
(client.getInputStream());
oos = new ObjectOutputStream
(client.getOutputStream());
} catch(Exception e1) {
try {
client.close();
}catch(Exception e) {
System.out.println(e.getMessage());
}
return;
}
this.start();
}


public void run() {
try {
oos.writeObject(new Date());
oos.flush();
// close streams and connections
ois.close();
oos.close();
client.close();
} catch(Exception e) {}
}
}

20 :: Explain How does the client receives the object and prints the date?

The client, DateClient, does not have to send any messages to the DateServer once a connection has been established. It simply receives a Date object that represents the current day and time of the remote machine. The client receives the object and prints the date as shown in Code Sample.

Code Sample: DateClient.java
import java.io.*;
import java.net.*;
import java.util.*;

public class DateClient {
public static void main(String argv[]) {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket socket = null;
Date date = null;
try {
// open a socket connection
socket = new Socket("yourMachineNameORipAddress", 3000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// read an object from the server
date = (Date) ois.readObject();
System.out.print("The date is: " + date);
oos.close();
ois.close();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}

To run this example, the first step is to replace the bold line in DateClient with the machine name or IP address where the DateServer will run. If both, the DateServer and DateClient, will run on the same machine then you can use "localhost" or "127.0.0.1" as the machine name. The next step is to compile the source files DateServer.java and DateClient.java. Then run the DateServer in one window (if you are working under Windows) or in the background (if you are working under UNIX) and run the DateClient. The client should print the current date and time of the remote machine.

21 :: Explain How to transport your own custom objects?

In this example, write an array multiplier server. The client sends two objects, each representing an array; the server receives the objects, unpack them by invoking a method and multiplies the arrays together and sends the output array (as an object) to the client. The client unpacks the array by invoking a method and prints the new array.

Start by making the class, whose objects will be transportable over sockets, serializable by implementing the Serializable interface as shown in Code Sample

Code Sample : SerializedObject.java
import java.io.*;
import java.util.*;

public class SerializedObject
implements Serializable {
private int array[] = null;

public SerializedObject() {
}

public void setArray(int array[]) {
this.array = array;
}

public int[] getArray() {
return array;
}
}

The next step is to develop the client. In this example, the client creates two instances of SerializedObject and writes them to the output stream (to the server), as shown from the source code in Code Sample.

Code Sample: ArrayClient.java
import java.io.*;
import java.net.*;

public class ArrayClient {
public static void main(String argv[])
{
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
// two arrays
int dataset1[] = {3, 3, 3, 3, 3, 3, 3};
int dataset2[] = {5, 5, 5, 5, 5, 5, 5};
try {
// open a socket connection
Socket socket = new Socket("YourMachineNameORipAddress",
4000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// create two serialized objects
SerializedObject so1 = new SerializedObject();
SerializedObject so2 = new SerializedObject();
SerializedObject result = null;
int outArray[] = new int[7];
so1.setArray(dataset1);
so2.setArray(dataset2);
// write the objects to the server
oos.writeObject(so1);
oos.writeObject(so2);
oos.flush();
// read an object from the server
result = (SerializedObject) ois.readObject();
outArray = result.getArray();
System.out.print("The new array is: ");
// after unpacking the array, iterate through it
for(int i=0;i<outArray.length;i++) {
System.out.print(outArray[i] + " ");
}
oos.close();
ois.close();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}

22 :: RMI vs. Sockets and Object Serialization

RMI vs. Sockets and Object Serialization
The Remote Method Invocation (RMI) is a Java system that can be used to easily develop distributed object-based applications. RMI, which makes extensive use of object serialization, can be expressed by the following formula:

RMI = Sockets + Object Serialization + Some Utilities

The utilities are the rmi registry and the compiler to generate stubs and skeletons.

If you are familiar with RMI, you would know that developing distributed object-based applications in RMI is much simpler than using sockets. So why bother with sockets and object serialization then?

The advantages of RMI in comparison with sockets are:

* Simplicity: RMI is much easier to work with than sockets
* No protocol design: unlike sockets, when working with RMI there is no need to worry about designing a protocol between the client and server -- a process that is error-prone.

The simplicity of RMI, however, comes at the expense of the network. There is a communication overhead involved when using RMI and that is due to the RMI registry and client stubs or proxies that make remote invocations transparent. For each RMI remote object there is a need for a proxy, which slows the performance down.
(by)Qusay H. Mahmoud

23 :: 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;

}

24 :: 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.

25 :: 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.
Socket Programming Interview Questions and Answers
62 Socket Programming Interview Questions and Answers