现在的位置: 首页 > 综合 > 正文

局域网多人聊天系统

2014年07月25日 ⁄ 综合 ⁄ 共 7546字 ⁄ 字号 评论关闭

        这是前段时间写的一个局域网多对多聊天系统,使用socket编程和TCP/IP协议进行数据传输。总体就两个部分,一个是客户端,还有一个是服务器端。其实这个系统编写起来还是很容易的。我这个小程序的亮点就在于:

1、有一个登陆界面;

2、登陆之后进入聊天界面后会有一个服务器的欢迎语句。

在这里给出程序的源代码。

package org.zsl.server;

//服务器部分
import java.io.DataInputStream;

import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/*
 * ChatServer类	服务器
 *  main() 			启动程序入口
 *  start1()		启动服务器,无线循环等待客户端
 * 
 * ServerThread类			实现了Runnable接口 
 *	ServerThread(Socket s)	构造方法
 *	send()					发送数据给客户端
 *	run()					覆写方法,接收数据并发送给所有的客户端	
 * */

public class ChatServer {

	private static boolean isRun = false;	//标识符

	private ServerSocket serverSocket = null;		//服务器
	
	private Socket client = null;
	
	
	private String name = null;
	
	List<ServerThread> st = new ArrayList<ServerThread>();		//st集合用来装产生的服务器线程
	
	public static void main(String[] args) {	//启动方法
		
		System.out.println("服务器启动!");
		new ChatServer().start1();
		
	}
	
	private void start1() {

		try {
			serverSocket = new ServerSocket(8888);		//实例化服务器,开启端口
			isRun = true;								//改变标识符
		} catch (BindException e) {
			System.out.println("端口使用中");
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {

			while (isRun) {			//无限循环

				client = serverSocket.accept();		//等待客户端连接,阻塞
				
				ServerThread serverThread = new ServerThread(client);	//一个客户端连接产生了一个服务器的线程
				
				
				
				st.add(serverThread);					//将线程加入结合
				
				name = serverThread.dis.readUTF();
				
				serverThread.setName(name);
				
				new Thread(serverThread).start();		//启动线程
				
				for (int i = 0; i < st.size(); i++) {	//遍历所有的线程
					
					ServerThread temp = st.get(i);
					
					temp.send("<服务器> 欢迎 "+this.name+" 进入聊天室!\n");	//向所有的线程发送信息
				}
				
				
				// dis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				serverSocket.close();		//关闭服务器
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	class ServerThread implements Runnable {

		private Socket client;			//定义客户端
		
		private DataInputStream dis = null;			//定义输入流
		
		private DataOutputStream dos = null;		//定义输出流
		
		private boolean bConnected = false;			//定义标志位
		
		private boolean flag = true;
		
		private String name = null;		//定义用户姓名
		
		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public ServerThread(Socket s) {
			this.client = s;
			
			try {
				dis = new DataInputStream(s.getInputStream());		//实例化接收客户端的信息的对象
				
				dos = new DataOutputStream(s.getOutputStream());	//实例化向客户端发送信息对象
				
				bConnected = true;
				
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		public void send(String str) {		//发送信息的方法
			try {
				dos.writeUTF(str);
			} catch (IOException e) {
				st.remove(this);

			}
		}

		@Override
		public void run() {

			try {
				
				while (bConnected) {
					
					String str = dis.readUTF();
					
					for (int i = 0; i < st.size(); i++) {	//遍历所有的线程
						
						ServerThread temp = st.get(i);
						
						temp.send("<"+this.name+"  "+new Date()+">\n"+"  "+str);	//向所有的线程发送信息
					}
					
				}
			} catch (EOFException e) {
				System.out.println("client closed");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (client != null) {
						client.close();
						client = null;
					}
					if (dis != null)
						dis.close();
					if (dos != null)
						dos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}

			}

		}

	}
}
package org.zsl.client;


import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

//登陆界面
public class Register {
	private JFrame frame = new JFrame("聊天系统登陆界面");
	
	private JLabel lab = new JLabel("请输入姓名:",JLabel.CENTER);
	
	private JTextField name = new JTextField();
	
	private JButton submit=new JButton("登陆");
	
	private JButton reset=new JButton("重置");
	
	private String c_name = null;
	
	public String getName(){	//取得用户注册姓名
		return c_name;
	}
	
	public Register(){
		submit.addActionListener(new ActionListener(){		//采用匿名内部类,注册submit的事件监听
			public void actionPerformed(ActionEvent arg0){
				if(arg0.getSource()==submit){				//判断触发源是否是提交按钮
				
					c_name=name.getText();
					
					new ChatClient(c_name);	//将c_name传递到了ChatClient中
					
					frame.dispose();	//关闭本窗口
				}
			}
		});
		reset.addActionListener(new ActionListener(){//注册reset的时间监听
			public void actionPerformed(ActionEvent arg1){
				if(arg1.getSource()==reset){//这个按钮没有反应
					name.setText("");
				}
			}
		});
		frame.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent arg0){
				System.exit(1);
			}
		});
		
		
		frame.setLayout(null);
		
		lab.setBounds(25, 50, 100, 50);
		name.setBounds(135, 60, 150, 30);
		submit.setBounds(75, 120, 80, 30);
		reset.setBounds(190, 120, 80, 30);
		
		
		frame.add(lab);
		frame.add(name);
		frame.add(submit);
		frame.add(reset);
		
		
		
		int width = 350;
		int high = 240;
		int w = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2;
		int h = (Toolkit.getDefaultToolkit().getScreenSize().height - high) / 2;
		
		frame.setSize(width, high);
		
		frame.setLocation(w, h);
		
		frame.setVisible(true);
	}
	
	public static void main(String[] args) {
		new Register();
	}
}


package org.zsl.client;

//客户端部分
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JPanel;

public class ChatClient extends Frame {

	Socket socket = null;

	TextField inputChat = new TextField(); // 定义文本框用来输入数据

	TextArea showChat = new TextArea(); // 展示数据的地方

	JButton submit = new JButton("发送");

	JPanel pan = new JPanel();

	DataInputStream dis = null; // 接收流

	DataOutputStream dos = null; // 输出流

	private String c_name = null;

	private static boolean isRun = false;

	private boolean flag = true; // 让c_name的传递只有一次

	public ChatClient() {
	}

	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}

	public ChatClient(String name) {
		this.c_name = name;
		this.launchFrame();
	}

	public void launchFrame() { // Swing 界面
		this.setTitle("局域网聊天系统");

		int width = 510;
		int high = 360;

		this.setLayout(null);
		this.setSize(width, high);

		showChat.setBounds(5, 5, 490, 295);
		pan.setBounds(5, 305, 490, 45);

		pan.setLayout(null);
		inputChat.setBounds(5, 5, 400, 40);
		submit.setBounds(405, 5, 95, 40);

		// 居中地位
		int w = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2;
		int h = (Toolkit.getDefaultToolkit().getScreenSize().height - high) / 2;

		pan.add(inputChat);
		pan.add(submit);

		this.add(showChat);
		this.add(pan);

		this.setLocation(w, h);

		this.setVisible(true);

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				disconnect();
				System.exit(0);
			}
		});
		
		inputChat.addActionListener(new TextFieldListener()); // 输入窗口中添加监听
		submit.addActionListener(new TextFieldListener()); // 输入窗口中添加监听

		connectToServer(); // 连接服务器

		Thread clientThread = new Thread(new ClientThread());

		clientThread.start(); // 启动客户端线程
	}

	private void connectToServer() {
		try {
			socket = new Socket("125.221.225.105", 8888);

			dis = new DataInputStream(socket.getInputStream());

			dos = new DataOutputStream(socket.getOutputStream());
			isRun = true;
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void disconnect() { // 如果没连接上服务器则关闭输入输出流和客户端套接字

		// 关闭各种流之前必须先关闭接受线程
		try {
			if (dos != null) {
				dos.close();
			}
			if (dis != null) {
				dis.close();
			}
			if (socket != null) {
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private class ClientThread implements Runnable {

		@Override
		public void run() {

			try {

				if (flag) { // 启动客户端只传递一次姓名
					dos.writeUTF(c_name);
					flag = false;
				}

				while (isRun) { // 无线循环

					String str = dis.readUTF(); // 取得服务器端发送的消息

					// System.out.println(str);
					// showChat中的部分由以前的 和 现在的组成
					showChat.setText(showChat.getText() + str + '\n'); // 在showChat中显示

				}
			} catch (SocketException e) {
				System.out.println("bye");
			} catch (EOFException e) {

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

	}

	private class TextFieldListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			String s = inputChat.getText().trim();
			if (e.getSource() == submit) {
				if(!("".equals(s))){
					// showChat.setText(s);
					inputChat.setText("");
					try {
						dos.writeUTF(s);
						dos.flush();
						// dos.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			} else {
				// showChat.setText(s);
				inputChat.setText("");
				try {
					dos.writeUTF(s);
					dos.flush();
					// dos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}

		}

	}

}

抱歉!评论已关闭.