Java-Tcp通信,解决只能第一次接收到数据

今天老师让写一个服务端和客户端通信的小程序,本以为很快就能写完,但是在写的过程中却发现了自己很多的问题,所以写篇博客记录一下

写完测试的时候发现,客服端只能发第一次数据给服务端,后面发送的服务端都接受不到

//服务端        
    serverSocket=new ServerSocket(12900);
            socket=serverSocket.accept();
            inputStream=socket.getInputStream();
            byte[] bytes = new byte[1024];
            inputStream.read(bytes);
            String string = new String(bytes);
            System.out.println(string);

//客户端
 String mess=message.getText();
                outputStream=socket.getOutputStream();
                outputStream.write(mess.getBytes());
                message.setText("");

后面加上了循环,发现还是只能发送第一次数据

 try {
            serverSocket=new ServerSocket(12900);
              
           while (true){   
                socket=serverSocket.accept();//一直阻塞直到有人连接它          
               inputStream=socket.getInputStream();
               byte[] bytes = new byte[1024];
               inputStream.read(bytes);
               String string = new String(bytes);
//                message.append(string+"\n");
               System.out.println(string);
           }

        }

查了资料才知道,socket是阻塞式通信,accep()是会阻塞的和,read()也会阻塞,一直到有东西连接为止,或者有数据可读,所以在这个循环中,第一次的时候因为有客户端连接,所以能够执行后面的代码,输出数据,但后面开始就没有客户端连接,所以就一直阻塞在accept(),导致后面的没法执行

 try {
            serverSocket=new ServerSocket(12900);
             socket=serverSocket.accept(); 
           while (true){   
                         
               inputStream=socket.getInputStream();
               byte[] bytes = new byte[1024];
               inputStream.read(bytes);
               String string = new String(bytes);
//                message.append(string+"\n");
               System.out.println(string);
           }

        }

这样子就能够实现客户端一直给服务端发送数据了

我对上面的程序进行了下改进,加入了线程,每一次有客户端连接时,就建立一个线程处理这个客户端的收发数据,也可借此实现多客户端向服务端通信。

服务端线程类:

public class ServerThread extends Thread {
    private Socket socket;
    InputStream inputStream
    public  ServerThread(Socket socket){
        this.socket=socket;
    }
    public void run(){
        try {
            while (true){
                inputStream=socket.getInputStream();
                byte[] bytes = new byte[1024];
                inputStream.read(bytes);
                String string = new String(bytes);
                System.out.println(string);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务端:

                System.out.println("wait client connect....");
                serverSocket=new ServerSocket(8808);
                while (true){
                    socket=serverSocket.accept();//有连接会返回一个Socket,其作为参数传给服务端线程类
                    System.out.println("client successed !");
                    new ServerThread(socket).start();//有新的连接就建立一个对应的线程
                }

加入线程不好的地方就是,当线程多了会占内存,而你每个线程只执行一点点事情,就会造成内存浪费,而且线程多了,Cpu会在各个线程来回切换,造成Cpu效率低 

客户端:

                socket=new Socket("localhost", 12900);
                String mess=message.getText();
                outputStream=socket.getOutputStream();
                outputStream.write(mess.getBytes());
                message.setText("");
扫描二维码关注公众号,回复: 4192784 查看本文章

这是本人结合网上的方法,如有不对或者效率更好的方法,欢迎指出和请教。

其实,有个点我没明白,我没关闭输入流和Socket,不是应该是一直连接的吗能够一直接收到数据,为啥还需要循环才能一直接收到数据呢,要是有大佬能看到我这篇,希望帮我解答下,提前谢谢啦

猜你喜欢

转载自blog.csdn.net/qq_40866897/article/details/84284488