레이블이 socket인 게시물을 표시합니다. 모든 게시물 표시
레이블이 socket인 게시물을 표시합니다. 모든 게시물 표시

2012년 1월 5일 목요일

Writing a multithreaded Socket Server

출처 : http://www.javareference.com/jrexamples/viewexample.jsp?id=47


Writing a multithreaded Socket Server

This example demonstrates the creation of a multithreaded socket server application. The server is currently a simple Echo Server, which simply accepts what the client says and sends it back. The example demonstrates the basic infrastructure for a true multithreaded server application and can be directly enhanced to perform as any server application.
The EchoServer accepts multiple client connections and is capable of serving them simultaneously. It uses a new thread to service every new client, which allows it to accepts new clients even before all clients are serviced. The server also identifies each client connection with a unique ID, making it easy to identify clients if required.
The EchoServer only understands one command, “quit”. On receiving this command, it quits the thread servicing the client and closes the connections. Also worth noting are the various places where anetwork connection could fail. All conditions are handled gracefully by EchoServer, thus making sure that the server never leaves behind residual threads and that the client is not capable of crashing the server.

Example Code:
EchoServer.java : The Server application

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

public class EchoServer
{        
    ServerSocket m_ServerSocket;
    
    
    public EchoServer() 
    {
        try
        {
            // Create the server socket. 
            m_ServerSocket = new ServerSocket(12111);
        }
        catch(IOException ioe)
        {
            System.out.println("Could not create server socket at 12111. Quitting.");
            System.exit(-1);
        }
        
        System.out.println("Listening for clients on 12111...");
        
        // Successfully created Server Socket. Now wait for connections. 
        int id = 0;
        while(true)
        {                        
            try
            {
                // Accept incoming connections. 
                Socket clientSocket = m_ServerSocket.accept();
            
                // accept() will block until a client connects to the server. 
                // If execution reaches this point, then it means that a client 
                // socket has been accepted. 
                
                // For each client, we will start a service thread to 
                // service the client requests. This is to demonstrate a 
                // multithreaded server, although not required for such a 
                // trivial application. Starting a thread also lets our 
                // EchoServer accept multiple connections simultaneously. 
                
                // Start a service thread 
                
                ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
                cliThread.start();
            }
            catch(IOException ioe)
            {
                System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
                ioe.printStackTrace();
            }
        }
    }
    
    public static void main (String[] args)
    {
        new EchoServer();    
    }
    
    
    class ClientServiceThread extends Thread
    {
        Socket m_clientSocket;        
        int m_clientID = -1;
        boolean m_bRunThread = true;
        
        ClientServiceThread(Socket s, int clientID)
        {
            m_clientSocket = s;
            m_clientID = clientID;
        }
       
        public void run()
        {            
            // Obtain the input stream and the output stream for the socket 
            // A good practice is to encapsulate them with a BufferedReader 
            // and a PrintWriter as shown below. 
            BufferedReader in = null; 
            PrintWriter out = null;
            
            // Print out details of this connection 
            System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " + 
                             m_clientSocket.getInetAddress().getHostName());
                
            try
            {                                
                in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
                out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));
                
                // At this point, we can read for input and reply with appropriate output. 
                
                // Run in a loop until m_bRunThread is set to false 
                while(m_bRunThread)
                {                    
                    // read incoming stream 
                    String clientCommand = in.readLine();
                    
                    System.out.println("Client Says :" + clientCommand);
                    
                    
                    if(clientCommand.equalsIgnoreCase("quit"))
                    {
                        // Special command. Quit this thread 
                        m_bRunThread = false;   
                        System.out.print("Stopping client thread for client : " + m_clientID);
                    }
                    else
                    {
                        // Echo it back to the client. 
                        out.println(clientCommand);
                        out.flush();
                    }
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                // Clean up 
                try
                {                    
                    in.close();
                    out.close();
                    m_clientSocket.close();
                    System.out.println("...Stopped");
                }
                catch(IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }
        }
    }
}

EchoClient.java : The client application

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

// A client for our multithreaded EchoServer. 
public class EchoClient
{
    public static void main(String[] args)
    {
        // First parameter has to be machine name 
        if(args.length == 0)
        {
            System.out.println("Usage : EchoClient <serverName>");
            return;
        }
        
        Socket s = null;
        
        // Create the socket connection to the EchoServer. 
        try
        {
            s = new Socket(args[0], 12111);
        }        
        catch(UnknownHostException uhe)
        {
            // Host unreachable 
            System.out.println("Unknown Host :" + args[0]);
            s = null;
        }
        catch(IOException ioe)
        {
            // Cannot connect to port on given host 
            System.out.println("Cant connect to server at 12111. Make sure it is running.");
            s = null;
        }
        
        if(s == null)
            System.exit(-1);
        
        BufferedReader in = null;
        PrintWriter out = null;
        
        try
        {
            // Create the streams to send and receive information 
            in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
            
            // Since this is the client, we will initiate the talking. 
            // Send a string. 
            out.println("Hello");
            out.flush();
            // receive the reply. 
            System.out.println("Server Says : " + in.readLine());
            
            // Send a string. 
            out.println("This");
            out.flush();
            // receive a reply. 
            System.out.println("Server Says : " + in.readLine());
            
            // Send a string. 
            out.println("is");
            out.flush();
            // receive a reply. 
            System.out.println("Server Says : " + in.readLine());
            
            // Send a string. 
            out.println("a");
            out.flush();
            // receive a reply. 
            System.out.println("Server Says : " + in.readLine());

            // Send a string. 
            out.println("Test");
            out.flush();
            // receive a reply. 
            System.out.println("Server Says : " + in.readLine());
            
            // Send the special string to tell server to quit. 
            out.println("Quit");
            out.flush();
        }
        catch(IOException ioe)
        {
            System.out.println("Exception during communication. Server probably closed connection.");
        }
        finally
        {
            try
            {
                // Close the streams 
                out.close();
                in.close();
                // Close the socket before quitting 
                s.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }                
        }        
    }
}

Demonstration:
To run the server, compile the source and run it by typing "java EchoServer" on the command prompt.
>java EchoServer
Listening for clients on 12111...

The server indicates that it is listening for connections. To run the client, simply run java EchoClient localhost (if running on the same machine), substitute "localhost" with the machine name the server is running on, if over a network.

>java EchoClient localhost
Server Says : Hello
Server Says : This
Server Says : is
Server Says : a
Server Says : Test

On running the client, the above output will be displayed at the client side, and the following output, on the server side.

Accepted Client : ID - 0 : Address - 127.0.0.1
Client Says :Hello
Client Says :This
Client Says :is
Client Says :a
Client Says :Test
Client Says :Quit
Stopping client thread for client : 0...Stopped

2011년 12월 26일 월요일

Android LocalSocket / LocalServerSocket sample code

출처 : http://all4dev.blogspot.com/2009/02/android-localsocket-localserversocket.html


Wednesday, February 18, 2009

Android LocalSocket / LocalServerSocket sample code

Abstract: This short code sample demonstrates how one can to use LocalSocket (LocalServerSocket) in Android SDK.

Platforms: Android SDK 1.0 (Eclipse 3.4.1 + ADT 0.8.0)

Add one button into your layout (main.xml):
    <Button android:id="@+id/send_1_button"
            android:layout_width="fill_parent" android:layout_height="wrap_content"
            android:text="send 1 request"/>


And this simple code for your activity
import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

/**
*
* @author Denis Migol
*
*/
public class DemoActivity extends Activity {
    
    public static String SOCKET_ADDRESS = "your.local.socket.address";
    
    // background threads use this Handler to post messages to
    // the main application thread
    private final Handler handler = new Handler();
    
    public class NotificationRunnable implements Runnable {
        private String message = null;
        
        public void run() {
            if (message != null && message.length() > 0) {
                showNotification(message);
            }
        }
        
        /**
        * @param message the message to set
        */
        public void setMessage(String message) {
            this.message = message;
        }
    }
    
    // post this to the Handler when the background thread notifies
    private final NotificationRunnable notificationRunnable = new NotificationRunnable();
    
    public void showNotification(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
    
    class SocketListener extends Thread {
        private Handler handler = null;
        private NotificationRunnable runnable = null;
        
        public SocketListener(Handler handler, NotificationRunnable runnable) {
            this.handler = handler;
            this.runnable = runnable;
            this.handler.post(this.runnable);
        }
        
        /**
        * Show UI notification.
        * @param message
        */
        private void showMessage(String message) {
            this.runnable.setMessage(message);
            this.handler.post(this.runnable);
        }
        
        @Override
        public void run() {
            //showMessage("DEMO: SocketListener started!");
            try {
                LocalServerSocket server = new LocalServerSocket(SOCKET_ADDRESS);
                while (true) {
                    LocalSocket receiver = server.accept();
                    if (receiver != null) {
                        InputStream input = receiver.getInputStream();
                        
                        // simply for java.util.ArrayList
                        int readed = input.read();
                        int size = 0;
                        int capacity = 0;
                        byte[] bytes = new byte[capacity];
                        
                        // reading
                        while (readed != -1) {
                            // java.util.ArrayList.Add(E e);
                            capacity = (capacity * 3)/2 + 1;
                            //bytes = Arrays.copyOf(bytes, capacity);
                            byte[] copy = new byte[capacity];
                            System.arraycopy(bytes, 0, copy, 0, bytes.length);
                            bytes = copy;
                            bytes[size++] = (byte)readed;
                            
                            // read next byte
                            readed = input.read();
                        }
                        
                        showMessage(new String(bytes, 0, size));
                    }
                }
            } catch (IOException e) {
                Log.e(getClass().getName(), e.getMessage());
            }
        }
    }
    
    public static void writeSocket(String message) throws IOException {
        LocalSocket sender = new LocalSocket();
        sender.connect(new LocalSocketAddress(SOCKET_ADDRESS));
        sender.getOutputStream().write(message.getBytes());
        sender.getOutputStream().close();
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        new SocketListener(this.handler, this.notificationRunnable).start();
        
        Button send1 = (Button)findViewById(R.id.send_1_button);
        send1.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                try {
                    writeSocket("hello");
                } catch (IOException e) {
                    Log.e(getClass().getName(), e.getMessage());
                }
            }
            
        });
    }
}