www.1q.co.kr(park1q.com)

ID :  Password : Auto  

   ȸ¿ø:0¸í / ¼Õ´Ô:2¸í
 

 

Technote

ÀÚ·á ¹× °ü¸®ÆÁ

  • DBA Notes
  • Q & A

    ºÏ¸¶Å©
  • Asktom
       (Oracle ÀÇ ´ëÇ¥ Forum)
  • Technical Bulltin(KR)
       (±â¼úÁö¿ø°Ô½ÃÆÇ)
  • Dbazine

  •  

     


     [Cool]Multithreaded Client/Server Applications
    park1q  2013-06-01 21:57:56, Á¶È¸ : 4,383, Ãßõ : 1292







    Multithreaded Client/Server Applications


    Sockets Programming in Java

    A socket is one end-point of a two-way communication link between two programs running on the network. These two programs form a Client/Server application.

    In Client/Server applications the server normally listens to a specific port waiting for connection requests from a client. When a connection request arrives, the client and the server establish a dedicated connection over which they can communicate. During the connection process, the client is assigned a local port number, and binds a socket to it. The client talks to the server by writing to the socket and gets information from the server by reading from it. Similarly, the server gets a new local port number to communicate with the client. The server also binds a socket to its local port and communicates with the client by reading from and writing to it. The server can not use its specific port to comunicate with the client since it is dedicated only to listen for connection requests from other clients.

    The client and the server must agree on a protocol, that is, they must agree on the language of the information transferred back and forth through the socket.

    The java.net package in the Java development environment provides a class Socket which implements the client side and the class ServerSocket class which implements the server side of the two-way link.

    There 3 types of sockets:

    • Stream socket (To listen): class ServerSocket.
    • Stream socket: class Socket.
    • Datagram socket: class DatagramSocket.
    There are two communication protocols that one can use for socket programming: stream communication and dram communication.

    The stream communication protocol is known as TCP (transfer control protocol). Unlike UDP, TCP is a connection-oriented protocol. In order to do communication over the TCP protocol, a connection must first be established between the pair of sockets. While one of the sockets listens for a connection request (server), the other asks for a connection (client). Once two sockets have been connected, they can be used to transmit data in both (or either one of the) directions.

    The datagram communication protocol, known as UDP (user datagram protocol), is a connectionless protocol, meaning that each time you send datagrams, you also need to send the local socket descriptor and the receiving socket's address. As you can tell, additional data must be sent each time a communication is made.

    UDP is an unreliable protocol, there is no guarantee that datagrams you have sent will be received in the same order by the receiving socket. On the other hand, TCP is a reliable protocol; it is guaranteed that the packets you send will be received in the order in which they were sent.

    TCP is useful for implementing network services, such as remote login (rlogin, telnet) and file transfer (FTP) -- which require data of indefinite length to be transferred. UDP is less complex and is often used in implementing client/server applications in distributed systems built over local area networks.

    This document we will show how to program sockets in Java using the TCP/IP protocol.

    Opening a socket

    If you are programming a client, then you would open a socket like this:
     Socket MyClient;
    MyClient = new Socket("Machine name", PortNumber);
    or using the exception handling,
     Socket MyClient;
    try {
               MyClient = new Socket("Machine name", PortNumber);
    }
    catch (IOException e) {
         System.out.println(e);
    }
    Where Machine name is the machine you are trying to open a connection to, and PortNumber is the port (a number) on which the server you are trying to connect to is running. When selecting a port number, you should note that port numbers between 0 and 1023 are reserved are reserved for standard services, such as email, FTP, and HTTP.

    If you are programming a server, then this is how you open a socket:
     ServerSocket MyService;
    try {
        MyServerice = new ServerSocket(PortNumber);
            }
            catch (IOException e) {
               System.out.println(e);
            }
    When implementing a server you also need to create a socket object from the ServerSocket in order to listen for and accept connections from clients.
     Socket clientSocket = null;
    try {
        serviceSocket = MyService.accept();
            }
    catch (IOException e) {
        System.out.println(e);
    }

    Creating an input stream

    On the client side, you can use the DataInputStream class to create an input stream to receive response from the server:
     DataInputStream input;
    try {
        input = new DataInputStream(MyClient.getInputStream());
    }
    catch (IOException e) {
        System.out.println(e);
    }
    The class DataInputStream allows you to read lines of text and Java primitive data types in a portable way. It has methods such as read, readChar, readInt, readDouble, and readLine,. Use whichever function you think suits your needs depending on the type of data that you receive from the server.

    On the server side, you can use DataInputStream to receive input from the client:
     DataInputStream input;
    try {
          input = new DataInputStream(serviceSocket.getInputStream());
    }
    catch (IOException e) {
        System.out.println(e);
    }

    Create an output stream

    On the client side, you can create an output stream to send information to the server socket using the class PrintStream or DataOutputStream of java.io:
     PrintStream output;
    try {
        output = new PrintStream(MyClient.getOutputStream());
    }
    catch (IOException e) {
        System.out.println(e);
    }
    The class PrintStream has methods for displaying textual representation of Java primitive data types. Its Write and println methods are important here. Also, you may want to use the DataOutputStream:
     DataOutputStream output;
    try {
        output = new DataOutputStream(MyClient.getOutputStream());
    }
    catch (IOException e) {
        System.out.println(e);
    }
    The class DataOutputStream allows you to write Java primitive data types; many of its methods write a single Java primitive type to the output stream. The method writeBytes is a useful one.

    On the server side, you can use the class PrintStream to send information to the client.
     PrintStream output;
    try {
        output = new PrintStream(serviceSocket.getOutputStream());
    }
    catch (IOException e) {
        System.out.println(e);
    }

    Closing sockets

    You should always close the output and input stream before you close the socket. On the client side:
     try {
               output.close();
               input.close();
        MyClient.close();
    }
    catch (IOException e) {
        System.out.println(e);
    }
    On the server side:
     try {
        output.close();
        input.close();
        serviceSocket.close();
        MyService.close();
    }
    catch (IOException e) {
        System.out.println(e);
    }

    A simple Client/Server example


    The client

    This is a simple client which reads from the standard input a line and sends it to the echo server. It keeps then reading from the socket till it receives the "Ok" from the server. Once it received that then it breaks.
    //Example 23

    import java.io.*;
    import java.net.*;

    public class client {
        public static void main(String[] args) {

    // declaration section:
    // clientClient: our client socket
    // os: output stream
    // is: input stream

            Socket clientSocket = null;
            DataInputStream is = null;
            PrintStream os = null;
            DataInputStream inputLine =null;

    // Initialization section:
    // Try to open a socket on port 2222
    // Try to open input and output streams
                    
            try {
                clientSocket = new Socket("ti.utm.md", 2222);
                os = new PrintStream(clientSocket.getOutputStream());
                is = new DataInputStream(clientSocket.getInputStream());
                inputLine = new DataInputStream(new BufferedInputStream(System.in));
            } catch (UnknownHostException e) {
                System.err.println("Don't know about host");
            } catch (IOException e) {
                System.err.println("Couldn't get I/O for the connection to host");
            }

    // If everything has been initialized then we want to write some data
    // to the socket we have opened a connection to on port 2222

            if (clientSocket != null && os != null && is != null) {
                try {

    // keep on reading from/to the socket till we receive the "Ok" from the server,
    // once we received that then we want to break.

                    String responseLine;
                    os.println(inputLine.readLine());
                    while ((responseLine = is.readLine()) != null) {
                        System.out.println(responseLine);
                        if (responseLine.indexOf("Ok") != -1) {
                            break;
                        }
                        os.println(inputLine.readLine());
                    }
                    
    // clean up:
    // close the output stream
    // close the input stream
    // close the socket

                    os.close();
                    is.close();
                    clientSocket.close();  
                } catch (UnknownHostException e) {
                    System.err.println("Trying to connect to unknown host: " + e);
                } catch (IOException e) {
                    System.err.println("IOException:  " + e);
                }
            }
        }          
    }


    The server

    This is a simple echo server. As long as it receives data it echos that data back to the client appending them to the "From server :" string.
    //Example 24

    import java.io.*;
    import java.net.*;

    public class server {
        public static void main(String args[]) {

    // declaration section:
    // declare a server socket and a client socket for the server
    // declare an input and an output stream

            ServerSocket echoServer = null;
            String line;
            DataInputStream is;
            PrintStream os;
            Socket clientSocket = null;
              
    // Try to open a server socket on port 2222
    // Note that we can't choose a port less than 1023 if we are not
    // privileged users (root)

            try {
               echoServer = new ServerSocket(2222);
            }
            catch (IOException e) {
               System.out.println(e);
            }  

    // Create a socket object from the ServerSocket to listen and accept
    // connections.
    // Open input and output streams

            try {
               clientSocket = echoServer.accept();
               is = new DataInputStream(clientSocket.getInputStream());
               os = new PrintStream(clientSocket.getOutputStream());

    // As long as we receive data, echo that data back to the client.

               while (true) {
                 line = is.readLine();
                 os.println("From server: "+ line);
               }
            }  
            catch (IOException e) {
               System.out.println(e);
            }
        }
    }



    A multithreaded Client/Server example

    This is a multithreaded chat application. The client uses two threads to interact with the server and with the standard input. The server uses a separate thread for every client. It spawns a new client thread every time a new connection from a client is established.

    The chat client

    This is the multithreaded chat client. It uses two threads: one to read the data from the standard input and to sent them to the server, the other to read the data from the server and to print them on the standard output.
    //Example 25

    import java.io.*;
    import java.net.*;

    public class MultiThreadChatClient implements Runnable{
        
        // Declaration section
        // clientClient: the client socket
        // os: the output stream
        // is: the input stream
        
        static Socket clientSocket = null;
        static PrintStream os = null;
        static DataInputStream is = null;
        static BufferedReader inputLine = null;
        static boolean closed = false;
        
        public static void main(String[] args) {
            
            // The default port        
            
            int port_number=2222;
            String host="localhost";
            
            if (args.length < 2)
                {
                    System.out.println("Usage: java MultiThreadChatClient n"+
                                       "Now using host="+host+", port_number="+port_number);
                } else {
                    host=args[0];
                    port_number=Integer.valueOf(args[1]).intValue();
                }
            // Initialization section:
            // Try to open a socket on a given host and port
            // Try to open input and output streams
            try {
                clientSocket = new Socket(host, port_number);
                inputLine = new BufferedReader(new InputStreamReader(System.in));
                os = new PrintStream(clientSocket.getOutputStream());
                is = new DataInputStream(clientSocket.getInputStream());
            } catch (UnknownHostException e) {
                System.err.println("Don't know about host "+host);
            } catch (IOException e) {
                System.err.println("Couldn't get I/O for the connection to the host "+host);
            }
            
            // If everything has been initialized then we want to write some data
            // to the socket we have opened a connection to on port port_number
            
            if (clientSocket != null && os != null && is != null) {
                try {
                    
                    // Create a thread to read from the server
                    
                    new Thread(new MultiThreadChatClient()).start();
                    
                    while (!closed) {
                        os.println(inputLine.readLine());
                    }
                    
                    // Clean up:
                    // close the output stream
                    // close the input stream
                    // close the socket
                    
                    os.close();
                    is.close();
                    clientSocket.close();  
                } catch (IOException e) {
                    System.err.println("IOException:  " + e);
                }
            }
        }          
        
        public void run() {                
            String responseLine;
            
            // Keep on reading from the socket till we receive the "Bye" from the server,
            // once we received that then we want to break.
            try{
                while ((responseLine = is.readLine()) != null) {
                    System.out.println(responseLine);
                    if (responseLine.indexOf("*** Bye") != -1) break;
                }
                closed=true;
            } catch (IOException e) {
                System.err.println("IOException:  " + e);
            }
        }
    }

    The chat server

    This is a multithreaded chat server. It uses a separate thread for every client. It spawns a new client thread every time a new connection from a client is established. This client thread opens the input and the output streams for a particular client, ask the client's name, informs all the clients currently connected to the server about the fact that a new client has joined the chat room, and as long as it receive data, echos that data back to all other clients. When the client leaves the chat room this thread informs also all the clients about that and terminates.
    //Example 26

    import java.io.*;
    import java.net.*;

    public class MultiThreadChatServer{

        // Declaration section:
        // declare a server socket and a client socket for the server
        // declare an input and an output stream
        
        static  Socket clientSocket = null;
        static  ServerSocket serverSocket = null;

        // This chat server can accept up to 10 clients' connections

        static  clientThread t[] = new clientThread[10];          
        
        public static void main(String args[]) {
            
            // The default port

            int port_number=2222;
            
            if (args.length < 1)
                {
                    System.out.println("Usage: java MultiThreadChatServer n"+
                                       "Now using port number="+port_number);
                } else {
                    port_number=Integer.valueOf(args[0]).intValue();
                }
            
            // Initialization section:
            // Try to open a server socket on port port_number (default 2222)
            // Note that we can't choose a port less than 1023 if we are not
            // privileged users (root)

            try {
                serverSocket = new ServerSocket(port_number);
            }
            catch (IOException e)
                {System.out.println(e);}
            
            // Create a socket object from the ServerSocket to listen and accept
            // connections.
            // Open input and output streams for this socket will be created in
            // client's thread since every client is served by the server in
            // an individual thread
            
            while(true){
                try {
                    clientSocket = serverSocket.accept();
                    for(int i=0; i<=9; i++){
                        if(t[i]==null)
                            {
                                (t[i] = new clientThread(clientSocket,t)).start();
                                break;
                            }
                    }
                }
                catch (IOException e) {
                    System.out.println(e);}
            }
        }
    }

    // This client thread opens the input and the output streams for a particular client,
    // ask the client's name, informs all the clients currently connected to the
    // server about the fact that a new client has joined the chat room,
    // and as long as it receive data, echos that data back to all other clients.
    // When the client leaves the chat room this thread informs also all the
    // clients about that and terminates.

    class clientThread extends Thread{
        
        DataInputStream is = null;
        PrintStream os = null;
        Socket clientSocket = null;      
        clientThread t[];
        
        public clientThread(Socket clientSocket, clientThread[] t){
            this.clientSocket=clientSocket;
            this.t=t;
        }
        
        public void run()
        {
            String line;
            String name;
            try{
                is = new DataInputStream(clientSocket.getInputStream());
                os = new PrintStream(clientSocket.getOutputStream());
                os.println("Enter your name.");
                name = is.readLine();
                os.println("Hello "+name+" to our chat room.nTo leave enter /quit in a new line");
                for(int i=0; i<=9; i++)
                    if (t[i]!=null && t[i]!=this)  
                        t[i].os.println("*** A new user "+name+" entered the chat room !!! ***" );
                while (true) {
                    line = is.readLine();
                    if(line.startsWith("/quit")) break;
                    for(int i=0; i<=9; i++)
                        if (t[i]!=null)  t[i].os.println("<"+name+"> "+line);
                }
                for(int i=0; i<=9; i++)
                    if (t[i]!=null && t[i]!=this)  
                        t[i].os.println("*** The user "+name+" is leaving the chat room !!! ***" );
                
                os.println("*** Bye "+name+" ***");

                // Clean up:
                // Set to null the current thread variable such that other client could
                // be accepted by the server

                for(int i=0; i<=9; i++)
                    if (t[i]==this) t[i]=null;  
                    
                // close the output stream
                // close the input stream
                // close the socket
                
                is.close();
                os.close();
                clientSocket.close();
            }
            catch(IOException e){};
        }
    }

    Conclusion

    Sockets allows to implement Client/Socket applications and provide a powerful and flexibile infrastructure for network programming. There are some other classes fot network programming. If you are trying to connect to the World Wide Web, the URL class and related classes (URLConnection, URLEncoder) are probably more suitable than the socket classes to what you are doing. In fact, URLs are a relatively high level connection to the Web and use sockets as part of the underlying implementation.

    Exercises



    1. Study and try all the examples presented above.
    2. Modify the the multithreaded chat example such that the server can accept an unlimited number of clients.

    Useful links and credits:



    1. Sockets programming in Java: A tutorial



    Last Revised:



    Back to Concurrent Programming Page


      ÃßõÇϱâ ÇÁ¸°Æ®   ¸ñ·Ïº¸±â

     [Etc][Cool]Multithreaded Client/Server Applications  park1q  2013-06-01
    21:57:56
         [Etc][re] [Cool]Multithreaded Client/Server Applications  park1q  2013-06-05
    15:25:38

    Copyright 1999-2026 Zeroboard

     

     
     
    [Today:5 / Total:174372]    Design by p@rk1q