2 okaxina OKAXINA 于 2016.04.29 09:48 提问

Socket的输入输出问题

MyServer.java

 import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;

public class MyServer{

    //定义保存所有Socket的ArrayList,并将其包装为线程安全的
    public static List<Socket> socketList
        = Collections.synchronizedList(new ArrayList<>());
    public static void main(String[] args) throws IOException{
        ServerSocket ss = new ServerSocket(30000);
        while(true){
            //此行代码会阻塞,将一直等待别人的连接
            Socket s = ss.accept();
            socketList.add(s);
            //每当客户端连接后启动一个ServerThread线程为该客户端服务
            new Thread(new ServerThread(s)).start();
        }
    }

}

ServerThread

 import java.net.Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;

//负责处理每个线程通信的线程类
public class ServerThread implements Runnable{

    //定义当前线程所处理的Socket
    Socket s = null;
    //该线程所处理的Socket对应的输入流
    BufferedReader br = null;
    public ServerThread(Socket s) throws IOException{
        this.s = s;
        //初始化该Socket对应的输入流
        br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    }
    public void run(){
        try{
            String content = null;
            //采用循环不断地从Socket中读取客户端发过来的数据
            while((content = readFromClient()) != null){
                //遍历socketList中的每个Socket
                //将读到的内容向每个Socket发送一次
                for(Socket s : MyServer.socketList){
                    PrintStream ps = new PrintStream(s.getOutputStream());
                    System.out.println(content);
                    ps.println(content);
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    //定义读取客户端数据的方法
    private String readFromClient(){
        try{
            Thread.sleep(10000);
            return br.readLine();
        }
        //如果捕获到异常,则表明该Socket对应的客户端已经关闭
        catch(Exception e){
            //删除该Socket
            MyServer.socketList.remove(s);
        }
        return null;
    }

}

MyClient

 import java.net.Socket;
import java.io.PrintStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class MyClient{

    public static void main(String[] args) throws Exception{
        Socket s = new Socket("127.0.0.1", 30000);
        //客户端启动ClientThread线程不断地读取来自服务器的数据
        new Thread(new ClientThread(s)).start();
        //获取该Socket对应的输出流
        PrintStream ps = new PrintStream(s.getOutputStream());
        String line = null;
        //不断地读取键盘输入
        BufferedReader br = new BufferedReader(
            new InputStreamReader(System.in));
        while((line = br.readLine()) != null){
            //将用户的键盘输入内容写入Socket对应的输出流
            ps.println(line);
        }
    }

}

ClientThread

 import java.net.Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ClientThread implements Runnable{

    //该线程负责处理的Socket
    private Socket s;
    //该线程所处理的Socket对应的输入流
    BufferedReader br = null;
    public ClientThread(Socket s) throws IOException{
        this.s = s;
        br = new BufferedReader(
            new InputStreamReader(s.getInputStream()));
    }
    public void run(){
        try{
            String content = null;
            //不断地读取Socket输入流中的内容,并将这些内容打印输出
            while((content = br.readLine()) != null){
                System.out.println(content);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

照着书敲得,实现一个命令行聊天。
问题是:MyClient中控制台输入阻塞,当我输入数据时,ServerThread可以通过Socket的输入流获取数据,而ClientThread中的Socket的输入流不能(这里的输入流是为了获取ServerThread中输出数据的时候才用上)。

3个回答

CSDNXIAOD
CSDNXIAOD   2016.04.29 09:52

C++的输入输出问题
输入输出问题
一些输入输出的问题
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!

u010675729
u010675729   2016.04.29 15:18

代码没问题啊,你把结果截图看看,我运行你的代码也没问题

OKAXINA
OKAXINA 我没说代码有问题,我问的是: ServerThread和ClientThread获取了socket的inputStream并各自包装起来,而MyClient在控制台输入的数据写入到socket获取的OutputStream中。 最后读到写入的数据的只有ServerThread中的inputStream,ClientThread无法读到。
一年多之前 回复
OKAXINA
OKAXINA   2016.04.29 17:43

我没说代码有问题,我问的是:
ServerThread和ClientThread获取了socket的inputStream并各自包装起来,而MyClient在控制台输入的数据写入到socket获取的OutputStream中。
最后读到写入的数据的只有ServerThread中的inputStream,ClientThread无法读到。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!