guolanren 2016-04-29 01:48 采纳率: 0%
浏览 1503

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中输出数据的时候才用上)。

  • 写回答

2条回答 默认 最新

  • u010675729 2016-04-29 07:18
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题