2 pacosonswjtu PacosonSWJTU 于 2016.01.30 22:58 提问

Socket获取outputStream 抛出异常

0)功能简介:

利用 socket 模拟qq 的消息发送和接收功能。既可以接收消息,也可以发送消息,无论是server 还是 client。在server 和 client 端都开启了两个线程, 一个线程用于接收并打印消息,一个线程用于发送消息。

1)问题简介:

先启动 server ,后启动client 去连接server, client 端抛出异常,说, socket 获取outputStream失败。。找不到原因啊。。oh。 求高手解答。
图片说明

2)client代码如下:

 package com.corejava.chapter3;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class AnalogQQClient
{
    public static void main(String[] args) throws IOException
    {
        try(Socket socket = new Socket("127.0.0.1", 8189))
        {
            new Thread(new Runnable() // print server's info
            {
                @Override
                public void run()
                {
                    try
                    {
                        Scanner scanner = new Scanner(socket.getInputStream());
                        while(true)
                        {
                            if(scanner.hasNext())
                            {
                                String line = scanner.nextLine();
                                System.out.println("from client: " + line);
                                if(line.equals("bye"))
                                {
                                    break;
                                }                           
                            }                       
                        }
                    } catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }).start();

            new Thread(new Runnable() // send info typed to the server
            {
                @Override
                public void run()
                {
                    try
                    {
                        PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                        while(true)
                        {
                             Scanner scanner = new Scanner(System.in);
                             if(scanner.hasNext())
                             {
                                 writer.println("from server: " + scanner.nextLine());
                             }
                        }
                    } catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        finally
        {
            System.out.println("the client is closed !");
        }
    }
}

3)server 代码如下:

 package com.corejava.chapter3;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class AnalogQQServer
{
    public static void main(String[] args) throws IOException
    {
        try(ServerSocket serverSocket = new ServerSocket(8189))
        {
            Socket socket = serverSocket.accept();

            new Thread(new Runnable() // print client's info
            {
                @Override
                public void run()
                {
                    try
                    {
                        Scanner scanner = new Scanner(socket.getInputStream());
                        while(true)
                        {
                            if(scanner.hasNext())
                            {
                                String line = scanner.nextLine();
                                System.out.println("from client: " + line);
                                if(line.equals("bye"))
                                {
                                    break;
                                }                           
                            }                       
                        }
                    } catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }).start();

            new Thread(new Runnable() // send info typed to the client
            {
                @Override
                public void run()
                {
                    try
                    {
                        PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                        while(true)
                        {
                             Scanner scanner = new Scanner(System.in);
                             if(scanner.hasNext())
                             {
                                 writer.println("from server: " + scanner.nextLine());
                             }
                        }
                    } catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        finally
        {
            System.out.println("the server is closed !");
        }
    }
}


2个回答

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.01.31 06:52
已采纳

分析了下你的代码,根本原因是你用了jdk1.7的try()操作,将客户端的Socket写在try()后面了,导致启动的两个线程还在使用socket时,jdk已经自动将该socket关闭了。
修改方法很简单,将Client端的try()括号里面的代码挪到{}中,然后使用完成后手动关闭。

 try {
            Socket socket = new Socket("127.0.0.1", 8189);

这样修改后就可以正常通信了,但是你的通信终止操作还需要再设计下,因为你是开启了多个线程来通信的,怎么让客户端在收到bye的消息后也终止发送呢?
这个我觉得你还需要认真思考下。祝好,有问题再交流。

PacosonSWJTU
PacosonSWJTU 按照前辈所说, 我把client 的 Socket 放到 try 语句块中,socket 还是 关闭了。
接近 2 年之前 回复
PacosonSWJTU
PacosonSWJTU 前辈,大冬天的早上不到7点回答我的问题,实为感动。抱歉,今天太忙,晚回复了。回到正题, 正如你所说,我用的是带资源的try语句,
接近 2 年之前 回复
devmiao
devmiao   Ds   Rxr 2016.01.30 23:54
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!