Java TCP局域网通信

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tiana_/article/details/79305417

Java TCP局域网通信

涉及到的知识点

  • Java NIO,比如Buffer,selector。
  • TCP socket编程。
    -建议参考书籍 Java网络编程(第4版) (美Elliotte Rusty Harold)

前言

之前做了一个简单的基于android平台的局域网聊天app,搜索设备和聊天通信都采用的是UDP
想看代码的点这里
然后就像用TCP来实现聊天通信这块,但是发现网上大部分都是发送固定消息的,因此,就自己做了实时的。
最后将这部分代码整合到android,即搜索设备用UDP,聊天通信用TCP。
想看代码的点这里

结果图

通过获取客户端输入,实现一对一(一对多)实时通信

  • 客户端结果图
    客户端

  • 服务端结果图
    服务端

    当然也可以做到多个客户端给同一个服务端发送消息,这里就补贴图了。

代码

获取控制台输入部分

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
/**
 * 单独开一个进程,获取控制台输入,(自测CPU利用率飙升)
 */
public class SystemInput implements Runnable {

    List<String> list = new ArrayList<>();
    Scanner sc = new Scanner(System.in);
    String msg;
    @Override
    public void run() {
        while (sc.hasNext()) {
            msg = sc.nextLine();
            //System.out.println(msg);
            list.add(msg);
        }
    }

    public String getMsg() {
        Iterator<String> it = list.iterator();
        String message = null;
        if (it.hasNext()) {
            message = it.next();
            it.remove();
        }
        return message;
    }
}

客户端部分

public class ChatClient {

    private static int PORT = 1199;
    private static String ADDRESS = "localhost";

    static SystemInput input = new SystemInput();

    public static void main(String[] args) {
        new Thread(input).start();
        client();
    }

    private static void client() {
        Scanner sc;
        SocketAddress add;
        SocketChannel socketChannel;
        Selector selector;
        try {
            add = new InetSocketAddress(ADDRESS, PORT);
            socketChannel = SocketChannel.open(add);
            socketChannel.configureBlocking(false);
            selector = Selector.open();
            socketChannel.register(selector, 
            SelectionKey.OP_READ | SelectionKey.OP_WRITE);
            sc = new Scanner(System.in);
            System.out.println("Connect server successfully,you can chat now");
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        while (true) {

            try {
                selector.select();
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }

            Set<SelectionKey> readyKeys = selector.selectedKeys();
            Iterator<SelectionKey> it = readyKeys.iterator();

            while (it.hasNext()) {

                SelectionKey key = it.next();
                it.remove();

                try {
                    if (key.isReadable()) { // 一次最多接收1024字节数据
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        WritableByteChannel out = Channels.newChannel(System.out);
                        if (socketChannel.read(buffer) != -1) {
                            buffer.flip();
                            out.write(buffer);
                            buffer.clear();
                        }
                    } else if (key.isWritable()) {
                        String msg = input.getMsg(); // 获取控制台输入,单次最多发送1024字节数据
                        if (msg != null) {
                            msg = new Date() + ": " + msg + "\r\n";
                            ByteBuffer buf = ByteBuffer.allocate(1024);
                            buf.put(msg.getBytes(), 0, msg.getBytes().length);
                            buf.flip();
                            socketChannel.write(buf);
                        }
                    }
                } catch (IOException e) {
                    key.cancel();
                    try {
                        key.channel().close();
                        sc.close();
                    } catch (IOException ex) {
                    }
                    e.printStackTrace();
                }
            }
        }

    }
}

服务器部分

public class ChatServer {

    private static final int PORT = 1199;

    static SystemInput input = new SystemInput();

    public static void main(String[] args) {
        new Thread(input).start();
        ;
        server();
    }

    private static void server() {
        println("Listening for connections on port: " + PORT);

        ServerSocketChannel serverChannel;
        Selector selector;
        try {
            serverChannel = ServerSocketChannel.open();
            ServerSocket ss = serverChannel.socket();
            InetSocketAddress add = new InetSocketAddress(PORT);
            ss.bind(add);
            serverChannel.configureBlocking(false);
            selector = Selector.open();
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        while (true) {
            try {
                selector.select();
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }

            Set<SelectionKey> readyKeys = selector.selectedKeys();
            Iterator<SelectionKey> it = readyKeys.iterator();

            while (it.hasNext()) {
                SelectionKey key = it.next();
                it.remove();

                try {
                    if (key.isAcceptable()) {
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        println("Accepted connection from " + client);
                        println("You can chat now");
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                        client.configureBlocking(false);
                    }
                    if (key.isWritable()) { // 获取控制台输入,单次最多发送1024字节数据
                        SocketChannel client = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        String msg = input.getMsg();
                        if (msg != null) {
                            msg = new Date() + ": " + msg+"\r\n";
                            buffer.put(msg.getBytes(), 0, msg.getBytes().length);
                            buffer.flip();
                            client.write(buffer);
                            buffer.compact();
                        }
                    }
                    if (key.isReadable()) { // 一次最多接收1024字节数据
                        SocketChannel client = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        WritableByteChannel out = Channels.newChannel(System.out);
                        if(client.read(buffer) != -1) {
                            buffer.flip();
                            out.write(buffer);
                            buffer.clear();
                        }
                    }
                } catch (IOException e) {
                    key.cancel();
                    try {
                        key.channel().close();
                    } catch (IOException ex) {
                    }
                    e.printStackTrace();
                }
            }
        }

    }

    private static void println(Object obj) {
        System.out.println(obj);
    }
}
展开阅读全文

java Tcp通信问题

11-01

写了个简单的java Tcp服务器,为什么从客户端发数据不能马上显示出来,当客户端断开连接的时候才显示出来,请高手帮忙看看程序哪里有问题?rn[code=Java]import java.io.BufferedReader; rnimport java.io.BufferedWriter; rnimport java.io.InputStream; rnimport java.io.InputStreamReader; rnimport java.io.OutputStream; rnimport java.io.OutputStreamWriter; rnimport java.net.ServerSocket; rnimport java.net.Socket; rnpublic class TcpServer rn public static void main(String[] args) throws Exception rn /*if (args.length == 0) rn System.out.println("未输入端口号,格式:java TcoServer 端口号"); rn return; rn rn System.out.println("服务器已开启,等待客户机响应。。。"); rn */ rn //ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0])); rn ServerSocket serverSocket = new ServerSocket(9902); rn while (true) rn rn Socket socket = serverSocket.accept(); rn System.out.println(socket.getInetAddress().getHostAddress() + ":" rn + socket.getPort() + " 已连接!"); rn new Thread(new Send(socket)).start(); rn rn rn rn// 发送数据 rnclass Send implements Runnable rn rn public Send(Socket socket) rn rn this.socket = socket; rn rn private Socket socket; rn private InputStream in; rn private OutputStream out; rn private BufferedReader br; rn private BufferedWriter bw; rn public void run() rn rn try rn rn in = socket.getInputStream(); rn out = socket.getOutputStream(); rn br = new BufferedReader(new InputStreamReader(in)); rn bw = new BufferedWriter(new OutputStreamWriter(out)); rn while (true) rn rn String msg = br.readLine(); rn if (msg != null) rn rn //System.out.println(socket.getInetAddress().getHostAddress() rn //+ ":" + socket.getPort() + "已断开!"); rn //break; rn bw.write("服务器响应:-->" + msg + "\r\n"); rn System.out.println(msg);rn bw.flush();rn rn rn elsern rn break;rn rn //StringBuffer sb = new StringBuffer(msg); rn //msg = sb.reverse().toString(); //倒序输出rn rn rn rn catch (Exception e) rn rn //e.printStackTrace(); rn System.out.println(socket.getInetAddress().getHostAddress() rn + ":" + socket.getPort() + "已断开!");rn rnrn try rn rn br.close(); rn bw.close(); rn socket.close(); rn catch (Exception e) rn rn e.printStackTrace(); rn rn rn [/code] 论坛

没有更多推荐了,返回首页