Java学习笔记-网络编程Socket简易C/S应用

首先考虑服务器应该包含多个Socket线程,每个线程监听客户端发来的数据,并将数据发给所有客户端

public class Myserver{
	//定义保存所有Socket的ArrayList,并将其包装为线程安全的
		static List<Socket> socketList = Collections.synchronizedList(
			new ArrayList<>());
		
		public static void main(String[] args) 
			throws IOException{
			ServerSocket ss = new ServerSocket(3000);
			while(true) {
				Socket s = ss.accept();
				socketList.add(s);
				new Thread(new ServerThread(s)).start();
			}
}

实现了服务器端只负责接收客户端Socket的连接请求,每当客户端Socket连接到该ServerSocket之后,程序将对应Socket加入socketList集合中保存,并为该Socket启动一个线程,该线程负责处理Socket所有的通信任务。

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());
					ps.println(content);
				}
			}
		}catch(IOException){
			e.printStackTrace();
		}
	}
	//定义读取客户端数据的方法
	private String readFromClient(){
		try{
			return br.readLine();
		}catch(IOException e){
			MyServer.socketList.remove(s);
		}
		return null;
	}
}

.
.
.
.

其次每个客户端应该包含两个线程,一个负责读取用户的键盘输入,并将用户输入的数据写入Socket对应的输出流中;一个负责读取Socket对应输入流中的数据(从服务器端发送过来的数据),并当这些数据打印输出。其中负责读取用户键盘输入的线程由MyClient负责,也就是程序的主线程。

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);
		}
	}
}

主线程使用Socket连接到服务器之后,启动了ClientThread来处理该线程的Socket通信,ClientThread线程负责读取Socket输入流中的内容,并将这些内容在控制台打印出来。

public class ClientThread implements Runnable{
	//该线程负责处理的Socket
	private Socket s;
	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();
		}
	}
}

先运行MyServer类,在运行多个MyClient,然后可以在任何一刻客户端内通过键盘输入一些内容后按回车键,即可在所有客户端(包括自己)的控制台上收到刚刚输入的内容,即粗略的实现了一个C/S结构聊天室的功能

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值