Simple TcpClient and TcpServer in Java

 

package network.tcpclient;

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

public class SimpleClient {
    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("Usage: java network.tcpclient.SimpleClient host port");
            return ;
        }
        String host = args[0];
        int port = Integer.parseInt(args[1]);
        new Thread(new TcpClient(host, port)).start();
    }
}

class TcpClient implements Runnable {
    Socket socket;
    String host;
    int port;

    public TcpClient(String host, int port) {
        this.host = host;
        this.port = port;
    }
    public void run() {
        try {
            socket = new Socket(host, port);
            InputStream inFromHost = socket.getInputStream();
            OutputStream outToHost = socket.getOutputStream();
            InputStream inFromUser = System.in;
            OutputStream outToUser = System.out;
            byte[] buffer = new byte[1024];
            int count = 0;
            for (;;) {
                count = inFromUser.read(buffer);
                if (count <= 0) // EOF indicates a quit                                                                                                                 
                    break;
                outToHost.write(buffer, 0, count);
                count = inFromHost.read(buffer);
                outToUser.write(buffer, 0, count);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

package network.tcpserver;

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

public class EchoServer {
    public static void main(String[] args) {
        try {
            new Thread(new TcpServer(8989)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class TcpServer implements Runnable {
    private ServerSocket serverSocket;

    // constructor                                                                                                                                                      
    public TcpServer(int port) throws IOException {
        this.serverSocket = new ServerSocket(port);
    }

    public void run() {
        for (;;) {
            try {
                Socket socket = serverSocket.accept();
                new Thread(new EchoConnectionHandler(socket)).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } // try                                                                                                                                                        
    }     // run                                                                                                                                                        

}
abstract class ConnectionHandler implements Runnable {
    private Socket socket;

    // constructor                                                                                                                                                      
    public ConnectionHandler(Socket socket) {
        this.socket = socket;
    }


    public void run() {
        handleConversation(socket);
    }

    // should be overridden by derived classes                                                                                                                          
    abstract public void handleConversation(Socket socket);
}



class EchoConnectionHandler extends ConnectionHandler {
    public EchoConnectionHandler(Socket socket) {
        super(socket);
    }

    public void handleConversation(Socket socket) {
        try {
            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();
            byte[] buffer = new byte[8192];
            int count;
            while ((count = in.read(buffer))>=0) {
                out.write(buffer, 0, count);
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {socket.close();} catch (IOException e) {}
        }
    }
}

 後記:java

1. 增長socket.getLocalPort()方法後,打印信息以下網絡

root@localhost:/home/James/mypro/Network/TcpServer# java network.tcpserver.EchoServersocket

Server using port: 8989tcp

Connection using port: 8989ui

 

root@localhost:/home/James/mypro/Network/TcpClient# java network.tcpclient.SimpleClient localhost 8989this

Connection using port: 60822spa

hello.net

hello3d

 2. 默認狀況下,tcp server監聽全部本地的IP地址。以下是客戶端的打印:code

root@localhost:/home/James/mypro/Network/TcpClient# java network.tcpclient.SimpleClient localhost 8989

Connection using port: 60822

hello

hello

root@localhost:/home/James/mypro/Network/TcpClient# java network.tcpclient.SimpleClient 10.0.0.28 8989

Connection using port: 36185

hello

hello

root@localhost:/home/James/mypro/Network/TcpClient# java network.tcpclient.SimpleClient 10.0.0.29 8989

Connection using port: 37042

hello

hello

 3. 一個TCP socket用(src ip, src port, dst ip, dst port)來標識。

以下,增長如下代碼後

public void run() {
        for (;;) {
            try {
                Socket socket = serverSocket.accept();
                System.out.println("Local host: " + socket.getLocalAddress());
                System.out.println("Local port: " + socket.getLocalPort());
                System.out.println("Remote host is: " + socket.getInetAddress());
                System.out.println("Remote port is: " + socket.getPort());
                new Thread(new EchoConnectionHandler(socket)).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } // try                                                                                                                                                        
    }     // run

運行結果:

root@localhost:/home/James/mypro/Network/TcpServer# java network.tcpserver.EchoServer              

Server using port: 8989

Server reuse address: true

Local host: /127.0.0.1

Local port: 8989

Remote host is: /127.0.0.1

Remote port is: 38108

4. accept獲得的socket繼承listen socket的各類屬性,但並不繼承local address ,結果以下:

root@localhost:/home/James/mypro/Network/TcpServer# java network.tcpserver.EchoServer

listen socket using address: 0.0.0.0/0.0.0.0:8989

listen socket using port: 8989

listen socket reuse address: true

Local host: /127.0.0.1:8989

Local port: 8989

Remote host is: /127.0.0.1

Remote port is: 33309

增長的代碼段是:

public TcpServer(int port) throws IOException {
        this.serverSocket = new ServerSocket(port);
        System.out.println("listen socket using address: " + serverSocket.getLocalSocketAddress());
        System.out.println("listen socket using port: " + serverSocket.getLocalPort());
        System.out.println("listen socket reuse address: " + serverSocket.getReuseAddress());
    }

0.0.0.0表示此socket只綁定端口,監聽本機上全部網絡全部IP,具體和哪一個ip連,由路由器決定。參考以下博客:

http://hi.baidu.com/cpuramdisk/item/2e46c45f35fc5d3d33e0a90d

相關文章
相關標籤/搜索