Simple Server With fork() In C++


Server program which I have included in earlier post is really simple one. The main problem associated with that code is; it just accepts one client and serves to it and returns from the program. Generally servers are not like that. The next step of socket programming is that enhance the server to accept multiple client connections and function continuously. Most simplest way to do this is by putting accept (), read () and write () system calls in endless while loop.

while (true)
 {
  iClientStructLength = sizeof(sClientAddress);
  iNewFileDesciptor = accept(iSocketFD, (struct sockaddr*) 
&sClientAddress, &iClientStructLength);
  if(iNewFileDesciptor == -1)
  {
   perror("Error ocurred while accepting the connection!");
   exit(1);
  }
  else
   printf("Client is: %s\n", inet_ntoa(sClientAddress.sin_addr));

  bzero(zBuffer, 256);//Empty the buffer
  int iReadReturn = read(iNewFileDesciptor, zBuffer, 255);
  if(iReadReturn < 0)
  {
   perror("Error ocurred while reading from socket!");
  }
  printf("Simple server received a message: %s\n", zBuffer);
 
  int iWriteReturn = write(iNewFileDesciptor, 
"Hi there, welcome to the simple server", 38);
  if(iWriteReturn < 0)
  {
   perror("Error ocurred while writing to the socket!");
  }
  close(iNewFileDesciptor);
 }

This code segment shows the while loop part of the server which accepts multiple clients. All the other things are same as what I have included in earlier post . If you add this part to your server program and run it with simple client which we have already created you can see that it can accept multiple clients. Wait……There’s a problem..Have you noticed it??? Ok..it can accept multiple clients but servicing to those clients are done as the same order as they have connected. That means if you run the server program and then client program (Client1) (Do not send anything to server) and again client program (Client 2). Client 2 can’t send anything to server until client 1 sends something to server. Reason is that server program stuck in the while loop to complete read and write operations to already accepted client1. So server can’t serves to client2 until it finishes servicing to client1. In order to overcome this issue we can take few approaches. Let’s first see most simple approach of using threads. By using threads we let server program to accept client and assign a new thread to serve to that client until main thread accepting another client or doing some other useful task. In C++ fork() system call can be used to achieve this task. (fork() system call is not something use to create new thread but it creates new child process)

#include <sys/stdio.h> pid_t fork(void);

fork() system call take no arguments and returns the process ID. After calling to fork() both parent and child processes executes the next instruction following the fork call. Therefore we need to distinguish parent and child processes by examining there PID’s.
  • When execuitng fork() if any error occurred then it will return -1.
  • fork() returns 0 to the newly created child process.
  • fork() returns positive value to the parent process.
Following code segment shows how we can use fork() system call in our server program.
while(true)
 {
  iClientStructLength = sizeof(sClientAddress);
  iNewFileDesciptor = accept(iSocketFD, (struct sockaddr*) &sClientAddress, &iClientStructLength);
  if(iNewFileDesciptor == -1)
  {
   perror("Error ocurred while accepting the connection!");
   exit(1);
  }
  else
   printf("Client is: %s\n" ,inet_ntoa(sClientAddress.sin_addr));
  
  if(fork() == 0)
  {
   bzero(zBuffer, 256);
   int iReadReturn = read(iNewFileDesciptor, zBuffer, 255);
   if(iReadReturn < 0)
   {
    perror("Error ocurred while reading from socket!");
   }
   printf("Simple server received a message: %s\n", zBuffer);
 
   int iWriteReturn = write(iNewFileDesciptor, "Hi there, welcome to the simple server", 38);
   if(iWriteReturn < 0)
   {
    perror("Error ocurred while writing to the socket!");
   }
   close(iNewFileDesciptor);
  }
  close(iNewFileDesciptor);
 }
In here we let main program to accept the client connections and create separate child process to each accepted connection to reading and writing. Condition if(fork == 0) checks whether this process is child process and if it is so then let that child process to reading and writing to/from socket. How do we run this program in multiple client mode?
  • Just run server program
  • Run simple client program twice (or as many times as you want)
  • Then type and enter anything in any client
  • Server will reply to that particular client
So there’s no any order of how server serves to the clients. Since each client is servicing through separate process, processing can be done in any order. Complete server program can be found here . Next post will include how we use select() system call to achieve the same result without forking. Have a nice day…

Socket Programming (Programming a Simple Client) in C++


All right now let’s move to the second part of the basic client-server programming, that is programming the client. It is more similar to programming a server but it’s little bit easy. Because we only have to handle two system calls here; socket() and connect(). But if you did not read the post about programming a server then this post may confusing since I’ll not cover anything state there, so first read it from here .
Since clients are not listening to incoming connections hence not accepting any connections listen() and accept() system calls are not needed for client.

Socket()
Exact system call is
int socket (int domain, int type, int protocol)
So, it is same as server program’s socket system call.

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

int iSocketFD;
iSocketFD = socket(AF_INET, SOCK_STREAM, 0);
if(iSocketFD == -1)
{
 perror("Error while creating socket!");
 exit(1);
}

Connect()
Exact connect () system call is

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

int sockfd :- Socket descriptor returned by socket() system call
struct sockaddr *serv_addr :- this struct holds the information (IP and port number) about the destination server.
int addrlen :- Length of the serv_addr

If connect () fails due to any reason it will send -1.

Nothing much to do here also, you have already practiced how to fill above three parameters in server program’s bind () system call. Sockaddr struct can be set via filling values to sockaddr_in struct and later casting to Sockaddr.
struct sockaddr_in {

     short sin_family; // Address family

     unsigned short sin_port; // Port number

     struct in_addr sin_addr; // Internet address

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

};


As in server program let's set values for sockaddr_in

//create a variable of type struct sockaddr_in
struct sockaddr_in sServerAddress; 

int iPortNumber = 2500;

sServerAddress.sin_family = AF_INET; 

/*I’ll going to run both server and client on my local machine.
 If you wish to run your server on remote machine then use
 that machine’s IP address here. htons () function used to
 convert address to network byte order */
sServerAddress.sin_addr.s_addr = inet_addr("127.0.0.1");  

//convert integer port number in to network byte order.
sServerAddress.sin_port = htons(iPortNumber); 

Complete connect system call is listed in following code segment
iPortNumber = 2500;
sServerAddress.sin_family = AF_INET;
sServerAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
sServerAddress.sin_port = htons(iPortNumber); 
 
if (connect(iSocketFD,(sockaddr*)&sServerAddress,sizeof(sServerAddress)) == -1)
{
 perror("Error while connecting!");
 exit(1);
}

Read and Write

This is also similar to read and write we have done in server program. Just for fun let’s prompt client to enter some message and send it to server.

// Buffer to store send and receive information
char zBuffer[256]; 

bzero(zBuffer,256); // Empty the buffer
printf("Enter Message : "); // Prompt user to enter message

// get user input and put it to the buffer
fgets(zBuffer,255,stdin); 

//write number of bytes (specified by third argument) to the socket
int iReturnValue = write(iSocketFD,zBuffer,strlen(zBuffer));

bzero(zBuffer,256); // Empty the buffer

// Read number of bytes from the socket and put to the buffer.
int iReturnValue2 = read(iSocketFD,zBuffer,255); 

Complete code for reading and writing is given below.
char zBuffer[256];
bzero(zBuffer,256);

printf("Enter Message : ");
fgets(zBuffer,255,stdin);
 
int iReturnValue = write(iSocketFD,zBuffer,strlen(zBuffer));
if(iReturnValue < 0)
 perror("Error while writing to the server!");
 
bzero(zBuffer,256);
int iReturnValue2 = read(iSocketFD,zBuffer,255);
if(iReturnValue2 < 0)
 perror("Error while reading from socket!");

printf("Client Received a Message: %s\n", zBuffer); 
To test the client you need to first run the server code and then client code. Server will first prompt that Client’s IP address. Meantime client program will prompt user to enter the message and after entering the message it will send to the server. Server will respond to that message with welcome message. Complete client program can be download from here .

Socket Programming (Programming a Simple Server) in C++

Before going to in depth details about how to program a socket, it is better to have some idea about what is a socket and how it operates when communication happens.
Socket…it is an abstract concept of communication end point. It can be identified by associated IP address and Port. Basically there are two types of internet sockets which we have to worry. One is STREAM SOCKET and other is DATAGRAM SOCKET.
Stream socket operates as it’s name suggests. Create stream of bits at one end of the communication and transfer it to other end to receive as it is. Stream socket data transferring is reliable, connection oriented delivery. Data transmission is controlled by and quality is guaranteed by protocols like Transmission Control Protocol (TCP).
In Datagram Sockets, packet is created by attaching the destination IP address and sends it without establishing physical or logical connection between source and destination. User Datagram Protocol (UDP) governs the communication in this mode.
Also it is better to have some understanding about OSI 7 layer model which I do not try to include here.
OK! That’s more than enough about basic theories. Let’s start programming with famous and simple client-server model. In this model you have to first start up the server process and put it to a loop which never ends (Because web server should function 24*7 and serves to the clients). That server process should wait for client connections and after client connected; request handling need to be done. Generally client initiates the communication by sending request to the server; therefore client process is called as active participant while server is called as passive participant of the communication.
Following diagrams shows what exactly we should do in order to make a client and server.

In C and C++ socket (), bind (), listen (), accept (), etc. kind of system calls are used to make a connection between client and server. Let’s start with server side stuff.

Socket ()
Exact system call is
int socket (int domain, int type, int protocol)
In order to use this system call it is required to include types.h and socket.h header files

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

OK…what are those arguments then?
int domain: - this refers to protocol family which this socket should created on. There are many protocol families available such as AF_INET, AF_UNIX, AF_IPX, etc. If you are programming on IPv4 then use AF_INET or if it is IPv6 then use AF_INET6.
int type: - type of socket (Stream Socket or Datagram Socket) you are going to create. That means whether it is a SOCK_STREAM or SOCK_DGRAM. For now just use SOCK_STREAM as the value for this argument.
int protocol: - use 0 here. For socket type belongs to a particular protocol family has single protocol. You can get it by setting this value to 0 (zero)

If socket function succeeds then it returns the socket descriptor (simply an integer value) or -1 if any error occurred. Therefore check whether return value is -1 (any error occurred) and if it is so then return immediately.

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

int iSocketFD;
iSocketFD = socket(AF_INET, SOCK_STREAM, 0); 
if(iSocketFD == -1)
{
 perror("Error ocurred while crearting socket!");
 exit(1);
}

Bind ()
After creating a socket we have to associate a port for that socket. bind () system call is used for that purpose.
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)

int sockfd :- socket file descriptor which is returned by socket() system call.
struct sockaddr *my_addr :- Pointer to a struct sockaddr.
Int addrlen: - length of sockaddr.

2nd argument may little bit confusing. It is just a pointer to struct sockaddr which is given below.
struct sockaddr
{

     unsigned short sa_family; // address family, AF_xxx

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

};

This structure holds socket address information. To deal with this structure normally we used another structure.

struct sockaddr_in {

     short sin_family; // Address family

     unsigned short sin_port; // Port number

     struct in_addr sin_addr; // Internet address

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

};


It is important to remember that struct sockaddr_in* can be cast to struct sockaddr* and vice versa. As a programming practice first just set values for sockaddr_in structure and at the time of binding, cast it to sockaddr structure. sin_port and sin_addr should be in network byte order (I’ll give some details about this in later. For now if you supply port number as integer value then use htons() function to convert it to network byte order).
OK..one more structure to go. As you see internet address (sin_addr) should be supply through another structure called in_addr which is given below.

struct in_addr {

     unsigned long s_addr; // that’s a 32-bit long, or 4 bytes

};

Do you remember from where we reached to this point? We were in bind system call’s 2nd argument. In this argument we had to supply address and port number to bind with socket, for that we use above 3 structures. Now it’s time to set values for structures.
/* create a variable (really?) of type struct sockaddr_in.    
Using this variable it is possible to call
to variables inside the struct
(as similar way to create an object of a
class and calling to class members using that object).*/ 
struct sockaddr_in sServerAddress;

/*setting the address family*/
sServerAddress.sin_family = AF_INET;

/*set the address of machine which server runs on.
 If you don’t know about the server address or if
 server is connected and serves through multiple
 network interfaces then use  INADDR_ANY as the
 value (this will automatically fills the IP 
 address which server runs on). Just look how
 it calls to in_addr struct’s s_addr long variable.*/
sServerAddress.sin_addr.s_addr = INADDR_ANY; 
int iPortNumber = 2400;
/*set the port number. htons() function
 used to convert integer port number into
 network byte order.*/
sServerAddress.sin_port = htons(iPortNumber);

Those set of arguments are enough for normal usage of bind system call. Wait..we have one argument to fill in bind system call. Length of the sockaddr struct. Nothing to worry just use sizeof() operator.
sizeof(sServerAddress);

Following code segment shows the entire coding for bind system call.
struct sockaddr_in sServerAddress;
iPortNumber = 2500;
sServerAddress.sin_family = AF_INET;
sServerAddress.sin_addr.s_addr = INADDR_ANY;
sServerAddress.sin_port = htons(iPortNumber);

int iReturn = bind(iSocketFD, (struct sockaddr*) &sServerAddress,  sizeof(sServerAddress));
if(iReturn == -1)
{
 perror("Error ocurred while binding socket!");
 exit(1);
}


So far we have created a socket and bind it to an IP address and port. As a server what it should do next? Any guesses? Waiting…waiting…waiting……..yes that’s the point. It should wait for incoming connections. In programming terms, it should listen to client connections and as soon as client connects, that connection should be accepted and serve to the client. For listening purpose listen () system call is used.

listen()
Exact listen () system call is as follows.
int listen(int sockfd, int backlog);
int sockfd :- file descriptor returned by socket() system call
int backlog :- size of incoming connections queue. Incoming connections are waiting on this queue until those are accepted.
Listen will return -1 if any error occurred.
int iListenReturn = listen(iSocketFD, 5);
if(iListenReturn == -1)
{
 perror("Error ocurred while going to listen!");
 exit(1);
}

Accept()
Oh…..Client connection received to the server, what should I do now? Hey…you have to accept it and start your communication.
To accept client incoming connections at server side, accept () system call is used.
int accept(int sockfd, void *addr, int *addrlen);

sockfd :- file descriptor returned by socket() system call
addr :- pointer to the struct sockaddr_in of the client. This will contains the client address and port number.
Addrlen :- Pointer to the size of client’s sockaddr_in struct.

Accept system call will return new file descriptor for accepted connection. That file descriptor should used for further operations of a particular connection (i.e. sending and receiving information). At this point server has two file descriptors. One is which returned by socket () system call which is now listening to incoming connections and other one is which returned by accept () system call.
struct sockaddr_in sClientAddress; //struct variable to hold client information
socklen_t iClientStructLength; // variable to hold client strcuct sockaddr_in’s length
iClientStructLength = sizeof(sClientAddress); 
int iNewFileDesciptor  = accept(iSocket, (struct sockaddr *) &sClientAddress,  &iClientStructLength);

Exact coding of accept system call is as follows.
int iNewFileDesciptor;
struct sockaddr_in sClientAddress;
socklen_t iClientStructLength;
iClientStructLength = sizeof(sClientAddress);
iNewFileDesciptor = accept(iSocketFD, (struct sockaddr*) &sClientAddress, &iClientStructLength);
if(iNewFileDesciptor == -1)
{
 perror("Error ocurred while accepting the connection!");
 exit(1);
}

Read and Write
Now it’s time to read something from socket and write something to socket. After accepting client connection, client can send message/ information/ request to the server (which server reads from socket) and server can send message/ information/ response to the client (which server writes to the socket). For reading and writing purposes file descriptor which is returned by accept system call is used.

#include <sys/unistd.>

ssize_t read(int fd, void *buf, size_t count)

int fd :- file descriptor returned by accept system call
void* buf :- pointer to buffer to store read information
size_t count :- this number of bytes are read and putted to the buffer
On success read () will return number of bytes read from the socket and -1 will return if any error occurred.

#include <sys/unistd.>

ssize_t write(int fd, const void *buf, size_t count)
int fd :- file descriptor returned by accept system call
void* buf :- pointer to buffer to store information to be write to the socket.
size_t count :- this number of bytes write to the socket from buffer
On success write () will return the number of bytes written to the socket and -1 will return if any error occurred.
Following code segment shows the exact usage of read () and write () functions.

char zBuffer[256]; //create a buffer to store information read and write from/to socket
bzero(zBuffer, 256);//Empty the buffer
int iReadReturn = read(iNewFileDesciptor, zBuffer, 255);
if(iReadReturn < 0)
{
 perror("Error ocurred while reading from socket!");
}
int iWriteReturn = write(iNewFileDesciptor, "Hi there, welcome to the simple server", 38);
if(iWriteReturn < 0)
{
 perror("Error ocurred while writing to the socket!");
}
After everything is done just called to close () function to close the connection. Remember to close both file descriptors.

close(iNewSocket); close(iSocket);

Complete server code can be download from here . Client side programming will be available in next post. Just try to understand the server code, compile and run it. Good luck…..

Image drag and drop in java

Java provides multiple ways to drag component from one location and drop it to another location. Some basic components such as JTable, JList, JColorChooser, JTextArea, JTextField, JTextPane, etc have drag behavior by default. In those kind of components what we have to do is simply enable drag feature by using setDragEnabled(boolean b) method.
But when it comes to images Java does not provide such a method to associate drag behavior with an image. So, how we add drag behavior to an image? Nothing to worry we have many alternatives (listed below).



  • Simply use MouseListeners (i.e. MouseMotionListener interface)

  • By using java.awt.dnd package and associated classes with it

  • Associate image with JLabel as Icon and drag label


Let’s start with really simple one.

Image Drag and Drop using Mouse Motion Listener


This is the simplest way to achieve drag and drop for an image. You may wonder; you just need around 50 lines of code to do this.

  1. You need to import few classes/packages first.


  2. import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JComponent;
    import javax.swing.JFrame;


  3. Create a class by extending JComponent and implementing MouseMotionListener interface.



  4. public class ImageDrag extends JComponent implements MouseMotionListener{

    }


  5. Add two integer instance variables to keep track of the x and y locations of the image. You can initialize those two variables to some values which you need to draw your image when application starts (if not image draws in (0, 0) point or top-left corner of the panel). Add BufferedImage instance variable to load your image (you can use java.awt.Image type instead of java.awt.image.BufferedImage).


  6. Add main method and create JFrame to draw image. Set basic properties of JFrame such as closeOperation, size, LookandFeel.


  7. public static void main(String args[]){
    JFrame frame = new JFrame("Image DnD");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(450, 450);
    }



  8. Create an instance of class and add it to the JFrame. Set visibility of JFrame to true.


  9. public static void main(String args[]){
    JFrame frame = new JFrame("Image DnD");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(450, 450);
    ImageDrag imageDragComponent = new ImageDrag();
    frame.getContentPane().add(imageDragComponent);
    frame.setVisible(true);
    }

  10. Create a constructor for the class and load image which you want to drag and drop. Setup the MouseMotionListener by using method addMouseMotionListener().


  11. public ImageDrag(){
    initComponents();
    addMouseMotionListener(this);
    }

    public void initComponents(){
    try{
    image = ImageIO.read(new File("src/dndblog1/images/Mickey mouse.gif"));
    }
    catch(IOException ioe){ioe.printStackTrace();}
    }



    After loading image we can draw it on the JFrame. For that we can override the paint method of component.


    public void paint(Graphics g){
    g.drawImage(image, x, y, this);
    }


    Here image is BufferedImage instance variable and x, y are integer instance variables which I have created in step3. So this method draws a BufferedImage on the location specified by x and y.

  12. There are two methods come up with MouseMotionListener interface you have to add those two methods.
    mouseMoved(MouseEvent me) method is for handle mouse movement without clicking on the screen. For our purpose there’s no any need of this method so leave it as it is.

    public void mouseMovedMouseEvent me){
    }


    mouseDragged(MouseEvent me) method invokes when we dragged some component from one location to another. Now there’s a trick, think for a while what are the things that change when we drag an image from one location to another?
    Image is same. It just changes it’s location (that means x and y coordinates) what we have to do is track this x and y coordinates. For that MouseEvent class provides two methods. getX() method returns the dropped point’s x coordinate and getY() method returns the dropped point’s y coordinate (note that I’m just talking about dragging and dropping so this getX() and getY() methods have different meanings according to the context).
    Now our task is almost over we have to assign those getX() method’s return value to x position of image and getY() method’s return value to y position and reapint the image.


  13. public void mouseDragged(MouseEvent me){
    x = me.getX();
    y = me.getY();
    repaint();
    }


Just compile and run your code; you can drag and drop image. It is quite simple, isn’t it?
Comments are really valuable..:)
You can download full source code here