`
xiang37
  • 浏览: 434291 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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

阅读更多

在学习了,多线程和socket之后;就想实现这个功能;但是一直没有花时间去写。可能我学得比较杂吧。

 

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

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

 

 

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 ,可以启动用来和用户一对一的对话。

 

 

 

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循环时,判断线程中和那个用户绑定了,也不需要得到线程里面的具体信息了。这样一对一的聊天也很容易就实现了,这些只要有了这个主干下面的程序就好延伸了。

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

今后实现了,源码再和大家分享;不过现在网上也有很多开源的这种代码,但自己写出来感觉还是不同。

 

 

 

 

8
1
分享到:
评论
2 楼 lockemn 2011-10-31  
客户端接受线程有问题,当输入"bye"退出聊天室,socket连接关闭,假如此时接受线程刚好在执行is.readLine(),而is输入流中的socket已关闭,则会抛出java.net.SocketException: Socket closed.
1 楼 dopic 2011-04-15  

相关推荐

    vc++ 应用源码包_1

    实现了自绘控件,云端控制主要在CnComm类多线程串口通讯库, camerads-DirectShow使用示例 演示了摄像头的使用 CatListBoxDemo ListBox控件与其它控件阙套使用方法 CCAMS系统是一种用于局域网下的CS模式的软件...

    vc++ 应用源码包_2

    实现了自绘控件,云端控制主要在CnComm类多线程串口通讯库, camerads-DirectShow使用示例 演示了摄像头的使用 CatListBoxDemo ListBox控件与其它控件阙套使用方法 CCAMS系统是一种用于局域网下的CS模式的软件...

    vc++ 应用源码包_6

    实现了自绘控件,云端控制主要在CnComm类多线程串口通讯库, camerads-DirectShow使用示例 演示了摄像头的使用 CatListBoxDemo ListBox控件与其它控件阙套使用方法 CCAMS系统是一种用于局域网下的CS模式的软件...

    vc++ 应用源码包_5

    实现了自绘控件,云端控制主要在CnComm类多线程串口通讯库, camerads-DirectShow使用示例 演示了摄像头的使用 CatListBoxDemo ListBox控件与其它控件阙套使用方法 CCAMS系统是一种用于局域网下的CS模式的软件...

    vc++ 应用源码包_3

    实现了自绘控件,云端控制主要在CnComm类多线程串口通讯库, camerads-DirectShow使用示例 演示了摄像头的使用 CatListBoxDemo ListBox控件与其它控件阙套使用方法 CCAMS系统是一种用于局域网下的CS模式的软件...

    python入门到高级全栈工程师培训 第3期 附课件代码

    02 全局变量与局部变量 03 风湿理论之函数即变量 04 函数递归 05 函数递归补充 第16章 01 上节课回顾 02 函数作用域 03 函数作用域补充 04 匿名函数 05 函数式编程介绍 06 函数式编程尾递归调用优化 07 map函数 08...

Global site tag (gtag.js) - Google Analytics