通过socket完成本机的自发自接(java)

随手敲代码回顾下socket,先直接上代码了

public class TestThread {

    private static int[] port = {8090,8091,8092,8093,8094};

    public class SendThread implements Runnable{

        private int port;

        private String ip;

        public SendThread(int port,String ip){
            this.port = port;
            this.ip = ip;
        }

        @Override
        public void run() {
            Socket socket = new Socket();
            PrintWriter socketOut = null;
            SocketAddress remoteAddr = new InetSocketAddress(ip, port);
            try {
                socket.connect(remoteAddr,120000);
                Writer writer = new OutputStreamWriter(socket.getOutputStream(),"utf-8");
                socketOut = new PrintWriter(socket.getOutputStream());
                socketOut.write("*");
                socketOut.flush();
                socket.shutdownOutput();
                System.out.println("往"+ip+":"+port+"发送*");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public class ReceiveThread implements Runnable{

        private int port;

        public ReceiveThread(int port){
            this.port = port;
        }

        @Override
        public void run() {
            Socket socket = new Socket();
            ServerSocket server = null;
            try {
                server = new ServerSocket(port);
                server.setSoTimeout(600000);
                socket = server.accept();
                //获得ip地址
                String ip = socket.getInetAddress().getHostAddress();
                //跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。
                Reader reader = new InputStreamReader(socket.getInputStream(),"UTF-8");
                BufferedReader bufferedReader = new BufferedReader(reader);
                String result = bufferedReader.readLine();
                char[] chars = result.toCharArray();
                System.out.println("从"+ip+":"+port+"获取到"+chars[0]);
                reader.close();
                socket.close();
                server.close();;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void testSend(){
        for (int i = 0; i < 5; i++) {
            new Thread(new SendThread(port[i],"192.168.1.191")).run();
        }
    }

    @Test
    public void testReceive(){
        for (int i = 0; i < 5; i++) {
            new Thread(new ReceiveThread(port[i])).run();
        }
    }

}

简单的一个本机的自发自接,先启动接受方,再启动发送方,运行结果:


光从结果来说,乍一看没什么问题,但细心的同学可能会发现问题所在,且是一个很大的问题。这里我就不卖关子了,我就稍微在代码里面做下输出提示,在红色标注的地方插入

System.out.println("端口号:"+port+"开始接受");

结果再运行一下,先运行接收方,你会发现控制台只打印出了一句话,再运行发送方,就把内容都打印出来了

结果不是很令人满意,等于说按照了for循环执行的顺序来运行得出结果,那我开启多线程岂不是没有意义?


为什么会出现控制台只打印出一个结果?

我们都知道接受的时候会在accept的地方阻塞住,直到接受到消息才继续往下执行,换句话说控制台出现一个结果,恰恰表明了程序执行到第一个循环开启第一个线程执行accept的地方就卡主了。通过打断点你也可以发现,for循环执行到第一个线程开启的地方再往下就执行不下去了。原因就在于,开启线程使用的是run方法,而run方法并不是真正意义上的开启线程,只不过是把Runnable中的run方法执行了一遍而已,所以看似循环开启多个线程,实际上就只是按顺序把run方法挨个执行一遍而已。所以要开启多线程来接发,还是得调用start方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值