多线程聊天室

多线程聊天室


前面写成的聊天室,经过实际运行,我们很容易发现,写好的程序仅且仅可以运行一个客户端,而这显然是不行,下面引入多线程来改进代码。

服务器端

package com.tedu.socket;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 聊天室服务器端
 * @author Wildmess
 *
 */
public class Server {

	/*
	 * java.net.ServerSocket
	 * 服务器端运行这个类的对象
	 * 1.申请服务端口
	 * 2.能够监听客户端发送过来的信息
	 */
	private ServerSocket server;
	private PrintWriter[] allout = {};
	private static int count = 0;

	public Server() {
		try {
			/*
			 * 实例化ServerSocket对象
			 * 向操作系统申请端口
			 * 如果这个端口被占用就会发生异常
			 */
			System.out.println("服务器正在启动……");
			server = new ServerSocket(8088);
			InetAddress ip = InetAddress.getLocalHost();
			System.out.println("服务器"+ ip +"启动完毕");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void start() {
		/*
		 * 返回值使用一个Socket
		 * server.accept()
		 * 这个方法是一个阻塞方法,调用后,程序暂停等待客户端的信息发送过来
		 * 没有信息过来就一直等
		 */
		try {

			System.out.println("等待客户端连接……");

			while(true) {
				Socket socket = server.accept();//等价于正常情况下的Scanner
				count++;
				System.out.println("第" + count + "个新的客户端连接了……");

				/*
				 * 将每一个客户端用于输出、输入的流等操作做成一个单独的线程
				 */
				ServerThread serverThread = new ServerThread(socket);
				Thread t = new Thread(serverThread);
				t.start();			
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		Server server = new Server();
		server.start();
	}

	class ServerThread implements Runnable{
		//客户端发送过来的socket名称及地址信息
		private Socket socket;
		private String ip;

		public ServerThread(Socket socket) {
			this.socket = socket;
			this.ip = socket.getInetAddress().getHostAddress();
		}

		public void run() {
			/*
			 * 获取输入流
			 */
			try {
				//从socket中获取输入流
				InputStream is = socket.getInputStream();
				InputStreamReader isr = new InputStreamReader(is,"utf-8");
				BufferedReader br = new BufferedReader(isr);

				String line=null;
				while((line = br.readLine())!=null) {
					System.out.println("[" + count + "]" + ip + ":" +line);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

客户端

package com.tedu.socket;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Scanner;

public class Client {
	/*
	 * java.net.socket
	 * Socket封装了TCP通信细节,我们只需要明确IP地址和端口号
	 * 像服务器端发送输出流(输入流)即可
	 */
	private Socket socket;

	public Client() {

		try {
			/*
			 * 实例化Socket需要俩个参数
			 * 1.服务器服务端IP地址
			 * 2.服务器端,端口号
			 * 
			 * 只要实例化成功就是连接成功
			 * 如果连接失败就会出现异常
			 * 
			 */
			System.out.println("正在连接服务器……");
			//socket = new Socket("localhost", 8088);
			socket = new Socket("172.117.55.169",8088);
			System.out.println("已连接服务器……");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 具体控制客户端说话的方法
	 */

	public void start() {
		/*
		 * 发送信息,需要输出流
		 * 输出到服务端
		 */
		try {
			OutputStream os = socket.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(os,"utf-8");
			BufferedWriter bw = new BufferedWriter(osw);
			PrintWriter pw = new PrintWriter(bw,true);

			Scanner sc = new Scanner(System.in);
			while(true) {
				String line = sc.nextLine();
				pw.println(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Client client = new Client();
		client.start();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值