多线程、socket、全局静态变量、聊天室




 

本程序虽然不是很完善,但是基本要求达到了。

功能:实现多个人同时聊天。类似于群聊天室

 

 

Java代码 复制代码  收藏代码
  1. package com.xiva.bean;  
  2.   
  3. import java.io.*;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. public class SocketServer {  
  10.     public static List<Socket> socketList = new ArrayList<Socket>();  
  11.     public static int number = 0;  
  12.     public static void main(String[] args) {  
  13.   
  14.         try{  
  15.                     //绑定服务端在8080端口  
  16.             ServerSocket server = new ServerSocket(8080);  
  17.             Socket socket;  
  18.             int count = 0;  
  19.               
  20.             while (true) {  
  21.                   
  22.                 //监听客户端程序  
  23.                 socket = server.accept();  
  24.                 count = count + 1;  
  25.                   
  26.                 System.out.println(socket.getInetAddress().getHostAddress());  
  27.                   
  28.                 //一个客户端连接后启动一个线程进行监听客户端消息  
  29.                   
  30.                 ReadThread readThread = new ReadThread(socket);  
  31.                 readThread.start();  
  32.                   
  33.                 socketList.add(socket);  
  34.             }  
  35.         } catch(IOException e){  
  36.             e.printStackTrace();  
  37.         }  
  38.     }  
  39. }  
  40.   
  41. class ThreadSocketServer extends Thread {  
  42.   
  43.     Socket server;  
  44.       
  45.     public ThreadSocketServer(){  
  46.           
  47.     }  
  48.       
  49.     public ThreadSocketServer(Socket s) {  
  50.         this.server = s;  
  51.     }  
  52.       
  53.     public void run() {  
  54.         try {  
  55.               
  56.             BufferedReader br = new BufferedReader(new InputStreamReader(  
  57.                     System.in));  
  58.             PrintWriter pw = new PrintWriter(server.getOutputStream());  
  59.               
  60.             //循环发送信息给客户端  
  61.             while (true) {  
  62.                 String s = br.readLine();  
  63.                 pw.println(s);  
  64.                 pw.flush();  
  65.                 System.out.println("Server:" + s);  
  66.             }  
  67.         } catch (IOException e) {  
  68.             e.printStackTrace();  
  69.         }  
  70.   
  71.     }  
  72.   
  73. }  
  74.   
  75. class ReadThread extends Thread {  
  76.   
  77.     private Socket socket;  
  78.     public ReadThread(Socket socket){  
  79.         this.socket = socket;  
  80.     }  
  81.     public void run() {  
  82.         try {  
  83.             BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  84.             String read=new String();  
  85.               
  86.             //循环接受客户端信息  
  87.             while(true)  
  88.             {  
  89.                   
  90.                 read=br.readLine();  
  91.                 System.out.println(socket.getInetAddress().getHostAddress() +"client说:"+read);  
  92.                 ArrayList<Socket> socketList = SocketServer.socketList;  
  93.                 for(int i = 0; i < socketList.size(); i ++){  
  94.                     Socket socket = socketList.get(i);  
  95.                     PrintWriter pw = new PrintWriter(socket.getOutputStream());  
  96.                     pw.println(read);  
  97.                     pw.flush();  
  98.                 }  
  99.                   
  100.                 if(read.equals("bye"))  
  101.                 {  
  102.                     break;  
  103.                 }  
  104.             }  
  105.             br.close();  
  106.             socket.close();  
  107.               
  108.         } catch (IOException e) {  
  109.             // TODO Auto-generated catch block  
  110.             e.printStackTrace();  
  111.         }  
  112.     }  
  113. }  
package com.xiva.bean;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class SocketServer {
	public static List<Socket> socketList = new ArrayList<Socket>();
	public static int number = 0;
	public static void main(String[] args) {

		try{
					//绑定服务端在8080端口
			ServerSocket server = new ServerSocket(8080);
			Socket socket;
			int count = 0;
			
			while (true) {
				
				//监听客户端程序
				socket = server.accept();
				count = count + 1;
				
				System.out.println(socket.getInetAddress().getHostAddress());
				
				//一个客户端连接后启动一个线程进行监听客户端消息
				
				ReadThread readThread = new ReadThread(socket);
				readThread.start();
				
				socketList.add(socket);
			}
		} catch(IOException e){
			e.printStackTrace();
		}
	}
}

class ThreadSocketServer extends Thread {

	Socket server;
	
	public ThreadSocketServer(){
		
	}
	
	public ThreadSocketServer(Socket s) {
		this.server = s;
	}
	
	public void run() {
		try {
			
			BufferedReader br = new BufferedReader(new InputStreamReader(
					System.in));
			PrintWriter pw = new PrintWriter(server.getOutputStream());
			
			//循环发送信息给客户端
			while (true) {
				String s = br.readLine();
				pw.println(s);
				pw.flush();
				System.out.println("Server:" + s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

class ReadThread extends Thread {

	private Socket socket;
	public ReadThread(Socket socket){
		this.socket = socket;
	}
    public void run() {
		try {
			BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			String read=new String();
			
			//循环接受客户端信息
			while(true)
			{
				
				read=br.readLine();
				System.out.println(socket.getInetAddress().getHostAddress() +"client说:"+read);
				ArrayList<Socket> socketList = SocketServer.socketList;
				for(int i = 0; i < socketList.size(); i ++){
					Socket socket = socketList.get(i);
					PrintWriter pw = new PrintWriter(socket.getOutputStream());
					pw.println(read);
					pw.flush();
				}
				
				if(read.equals("bye"))
				{
					break;
				}
			}
			br.close();
			socket.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

 

不用说了上面是socket的server端。

标题中提到了,全局静态变量;就是上面程序中的socketList。用来存储每一个连接到server端的socket.

在read线程中,同时向所有的client端发送信息。

 

 

其中类ThreadSocketServer ,可以启动用来和用户一对一的对话。

 

 

 

Java代码 复制代码  收藏代码
  1. package com.xiva.bean;  
  2.   
  3. import java.io.*;  
  4. import java.net.*;  
  5.   
  6.   
  7. public class TalkClient {  
  8.     public static void main(String args[]) {  
  9.         try{  
  10.             Socket socket=new Socket("192.168.0.64",8080);  
  11.           
  12.             ReadString read = new ReadString(socket);  
  13.             read.start();  
  14.               
  15.             BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));  
  16.               
  17.             PrintWriter os=new PrintWriter(socket.getOutputStream());  
  18.       
  19.             String readline=sin.readLine();  
  20.               
  21.             while(!readline.equals("bye")){  
  22.                 os.println(readline);  
  23.                 os.flush();  
  24.                 System.out.println("Client:"+readline);  
  25.                   
  26.                 readline=sin.readLine();  
  27.             }  
  28.             os.close();  
  29.   
  30.             socket.close();  
  31.         }catch(Exception e) {  
  32.             System.out.println("Error"+e);  
  33.         }  
  34.     }  
  35. }  
  36.   
  37. class ReadString extends Thread {  
  38.   
  39.     private Socket socket;  
  40.     public ReadString(Socket socket){  
  41.         this.socket = socket;  
  42.     }  
  43.     public void run() {  
  44.         try {  
  45.             BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  46.             //循环接受服务端信息  
  47.             while(true)  
  48.             {  
  49.                 String read = is.readLine();  
  50.                 System.out.println("Server:"+read);  
  51.                   
  52.                 if(read.equals("bye"))  
  53.                 {  
  54.                     break;  
  55.                 }  
  56.             }  
  57.             is.close();  
  58.             socket.close();  
  59.               
  60.         } catch (IOException e) {  
  61.             e.printStackTrace();  
  62.         }  
  63.     }  
  64. }  
package com.xiva.bean;

import java.io.*;
import java.net.*;


public class TalkClient {
	public static void main(String args[]) {
		try{
			Socket socket=new Socket("192.168.0.64",8080);
		
			ReadString read = new ReadString(socket);
			read.start();
			
			BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
			
			PrintWriter os=new PrintWriter(socket.getOutputStream());
	
			String readline=sin.readLine();
			
			while(!readline.equals("bye")){
				os.println(readline);
				os.flush();
				System.out.println("Client:"+readline);
				
				readline=sin.readLine();
			}
			os.close();

			socket.close();
		}catch(Exception e) {
			System.out.println("Error"+e);
		}
	}
}

class ReadString extends Thread {

	private Socket socket;
	public ReadString(Socket socket){
		this.socket = socket;
	}
    public void run() {
		try {
			BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			//循环接受服务端信息
			while(true)
			{
				String read = is.readLine();
				System.out.println("Server:"+read);
				
				if(read.equals("bye"))
				{
					break;
				}
			}
			is.close();
			socket.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
}

 

客户端程序,在于启动一个线程监视server端传过来的message,同时可以不断的发送信息给server端。

 

 

这样多人聊天室,便实现了。

 

扩展方向,可以在list中绑定其他信息,比如userInfo。当客户端连接时,发送给客户端有哪些其它客户在线。同样绑定了userInfo后,这样就可以for循环时,判断线程中和那个用户绑定了,也不需要得到线程里面的具体信息了。这样一对一的聊天也很容易就实现了,这些只要有了这个主干下面的程序就好延伸了。

还有需要注意的就是线程存在的时间,我们可能需要写一个定时器,不断唤醒程序,以及让其睡眠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值