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) {}
        }
    }
}

 后记:

1. 增加socket.getLocalPort()方法后,打印信息如下

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

Server using port: 8989

Connection using port: 8989

 

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

Connection using port: 60822

hello

hello

 2. 默认情况下,tcp server监听所有本地的IP地址。如下是客户端的打印:

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

 

 

 

 

转载于:https://my.oschina.net/u/158589/blog/64738

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值