通过多线程实现非阻塞TCP通信

来源:互联网 发布:java流程引擎框架 编辑:程序博客网 时间:2024/04/28 20:56

在tcp通信中,一般都是阻塞的,如果要实现非阻塞,我们可以使用多线程也可以使用nio中相关的类。这里我使用的是多线程的方式实现非阻塞。
服务器端:
1.创建ServerSocket对象,绑定监听端口;
2.调用accept()方法对客户端进行监听;
3.使用多线程对用户进行读操作,并反馈;
客户端:
1.创建Socket对象,通过IP和端口号和服务器进行连接;
2.分别使用多线程对服务器端进行读写操作;
代码如下:
服务器端:

package sency.one;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server {    private ServerSocket ss;    private int port = 8000;    public Server() throws IOException {        // 创建接收端的ServerSocket        ss = new ServerSocket(port);        System.out.println("服务器启动!!!");    }    public static void main(String args[]) throws IOException {        new Server().service();    }    private void service() {        // TODO Auto-generated method stub        while (true) {            Socket socket = null;            try {                // 通过accept()方法进行监听,返回一个socket                socket = ss.accept();                DataOutputStream os = new DataOutputStream(socket.getOutputStream());package sency.one;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server {    private ServerSocket ss;    private int port = 8000;    public Server() throws IOException {        // 创建接收端的ServerSocket        ss = new ServerSocket(port);        System.out.println("服务器启动!!!");    }    public static void main(String args[]) throws IOException {        new Server().service();    }    private void service() {        // TODO Auto-generated method stub        while (true) {            Socket socket = null;            try {                // 通过accept()方法进行监听,返回一个socket                socket = ss.accept();                DataOutputStream os = new DataOutputStream(socket.getOutputStream());                os.writeUTF("Welcome!");                os.flush();                //输出客户端端口                if (socket.isConnected()) {                    System.out.println("Port:" + socket.getPort());                }                // 采用多线程的方式处理                // 收信息线程                Thread receiveThread = new Thread(new ReHandler(socket));                receiveThread.start();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    // 收信息    class ReHandler implements Runnable {        private Socket socket = null;        public ReHandler(Socket socket) {            this.socket = socket;        }        public void run() {            try {                printMsg(socket);            } catch (IOException e) {                e.printStackTrace();            } finally {                try {                    if (socket != null) {                        socket.close();                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    // 在服务器端输出客户端发送的信息    private void printMsg(Socket socket) throws IOException {        DataInputStream is = new DataInputStream(socket.getInputStream());              String msg = "";        while ((msg = is.readUTF()) != null) {            System.out.println("来自:"+socket.getInetAddress()+"--"+socket.getPort());            System.out.println("#Client:" + msg);            if (msg.equals("bye")) {                break;            }            sendEcho(socket,msg);        }        is.close();    }    // 向客户端发送信息    private void sendEcho(Socket socket,String msg) throws IOException {        if(msg!=null){            DataOutputStream os = new DataOutputStream(socket.getOutputStream());            os.writeUTF("#Server:收到"+msg);            os.flush();        }    }}

客户端:

package sency.one;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;public class Client {    private Socket socket;    private String host = "localhost";    private int port = 8000;    public Client() throws IOException {        socket = new Socket(host, port);        System.out.println("客户端启动!!!");        System.out.println("Port:"+socket.getLocalPort());    }    public static void main(String args[]) throws IOException {        new Client().talk();    }    private void talk() {        // TODO Auto-generated method stub        // 采用多线程分别进行收发信息        // 发送线程        Thread sendThread = new Thread(new SendHandler());        sendThread.start();        // 收线程        Thread reThread = new Thread(new ReHandler());        reThread.start();    }    class SendHandler implements Runnable {        public void run() {            // TODO Auto-generated method stub            try {                sendMsg();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }finally {                try {                    if (socket != null) {                        socket.close();                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    class ReHandler implements Runnable {        public void run() {            // TODO Auto-generated method stub            try {                receiveMsg();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }finally {                try {                    if (socket != null) {                        socket.close();                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    //发信息    public void sendMsg() throws IOException {        DataOutputStream os = new DataOutputStream(socket.getOutputStream());        DataInputStream is = new DataInputStream(System.in);        String msg = null;        while ((msg = is.readLine()) != null) {            System.out.println("#Client:" + msg);            os.writeUTF(msg);            os.flush();            if(msg.equals("bye")){                break;            }        }           os.close();        is.close();    }    //收信息    private void receiveMsg() throws IOException{        DataInputStream is = new DataInputStream(socket.getInputStream());        String msg = null;        while((msg = is.readUTF())!=null){            System.out.println("#Service:"+msg);            if(msg.equals("bye")){                break;            }        }        is.close();    }}

遇到的问题:
我不知道有没有人和我一样在读写的时候用了BufferedReader和BufferedWriter,以至于在后面使用readLine()方法时尽管是多线程也一直处于阻塞状态,我找了一下午,后来改成使用DataOutput/InputStream以及对应的readUTF()和writeUTF()方法,这个问题就解决了,具体原因我想了很久也没想明白,有个猜测不确定,等下周问了老师得到准确的答案再来说吧!!!
立个Flag:接下来有时间的话自己再用nio实现一下非阻塞通信,到时候来更博!

0 0
原创粉丝点击