`
qq_24665727
  • 浏览: 120994 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论
阅读更多

我们在写一个聊天室的小项目时候,需要有客户端和服务器端;并且他们必须分开开发,不能有任何互相调用的语句出现!(并且运行的时候先运行服务端(只能一个),然后可以运行多个客户端)

 

一般我们先写好服务端:

package 聊天室服务端;

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

public class MyServer {
	public static List<Cthread> list=new ArrayList<Cthread>();
	public static void main(String[] args) {
		try {
			ServerSocket serversocket=new ServerSocket(9090);//创建一个服务端,端口号待会客户端连接要用
			System.out.println("服务端已经打开!等待连接....");
			while(true){//这里是一个无限循环,不停的等待着客户端来连接
			Socket socket=serversocket.accept();//这是一个堵塞方法,没人连接就不会往下面运行
			Cthread ct = new Cthread(socket);//每连上一个客户端,我就给他创建一个线程,专门去接收它的信息,以及广播给其他人
			ct.start();
			list.add(ct);//把线程都添加到一个列表,方便服务端管理
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

服务端还需要接收消息,还有广播消息的功能,所以没当连上一个客户端的时候,我们就给新建一个线程来专门接收它的消息,以及广播给其他人(客户端不与其他客户端有联系,所有信息发送给服务端,然后由它广播)

package 聊天室服务端;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketAddress;


/**
 * ,专门去接收它的信息,以及广播给其他人

 * @author yan
 *
 */
public class Cthread extends Thread{
	Socket socket;
	private BufferedWriter bout;
	private SocketAddress addr;
	public 	Cthread(Socket socket){
		this.socket=socket;
	}
	public void run(){
		// 获得客户端地址
		addr = socket.getRemoteSocketAddress();
		System.out.println("连了一个客户端:" + addr);

		// 通过Socket对象获得IO流
		try {
			OutputStream ops = socket.getOutputStream();
			InputStream ips = socket.getInputStream();

			// 包装成缓冲字符流
			OutputStreamWriter osr = new OutputStreamWriter(ops);
			bout = new BufferedWriter(osr);

			InputStreamReader isr = new InputStreamReader(ips);
			BufferedReader br = new BufferedReader(isr);
			
			String msg = "欢迎光临!\r\n";
			bout.write(msg);
			bout.flush();
			while (true) {
				// 服务端读取客户端发来的消息
				// 读取一行数据,读取到换行回车就不读取了
				String str = br.readLine();
				System.out.println( str);

				// 收到一个消息,就将消息广播给其它socket
				for (int i = 0; i < MyServer.list.size(); i++) {
					Cthread ct = MyServer.list.get(i);
					ct.sendMsg(str + "\r\n");
				}
			}
		} catch (Exception e) {
			System.out.println("客户端已经断开连接!");
		}
	
	}
	// 通过socket给客户端发送消息
		public void sendMsg(String msg) throws IOException {
			this.bout.write(msg);
			this.bout.flush();
		}
}

 

服务端以及完成

----------------------------------------------------------------------------------------------

接下来便是客户端了:

Client类里面主要包含界面构建,事件的触发

连接服务端的语句:

    socket = new Socket("127.0.0.1", 9090);//利用IP地址和端口号,来连接正在运行的服务器

 

 

package 聊天室客户端;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;

public class Client extends JFrame implements ActionListener{
	private Socket socket;
	private BufferedWriter bout;
	private BufferedReader br;
	private JTextPane pane;
	private JTextPane area;
	private static JTextField jt;
	private JButton btn1;
	private static JTextPane pane3;//用来显示在线人数,所以让其他对象都公用(目前没有做完这个功能)
	private boolean line=true;

	public static void main(String[] args) {
		Client c = new Client();
			JOptionPane.showMessageDialog(null, "请先设置昵称!");
			//如果不设置昵称,那么对话时就是显示的IP地址
			
	}
	
	public Client() {
		this.setTitle("聊天室");
		this.setBounds(200, 100, 800, 500);
		this.setDefaultCloseOperation(3);
		this.setLayout(null);

		// 显示接受的消息内容
		pane = new JTextPane();
		pane.setEditable(false);
		JScrollPane jsp = new JScrollPane(pane);
		jsp.setBounds(10, 10, 550, 300);
		jsp.setAutoscrolls(true);
		this.add(jsp);

		// 要发送的内容
		area = new JTextPane();
		JScrollPane jsp2 = new JScrollPane(area);
		jsp2.setBounds(10, 320, 440, 130);
		this.add(jsp2);

		
		JLabel label = new JLabel();
		label.setText("请设置昵称:");
		label.setBounds(460, 310, 100, 30);
		this.add(label);

		jt = new JTextField();
		jt.setText("");
		jt.setBounds(460, 340, 100, 30);
		this.add(jt);

		btn1 = new JButton("连接");
		btn1.setBounds(460, 380, 100, 30);
		btn1.addActionListener(this);
		this.add(btn1);
		
		
		JButton btn2 = new JButton("发送");
		btn2.setBounds(460, 420, 100, 30);
		btn2.addActionListener(this);
		this.add(btn2);
		
		
		// 显示在线人(还没有完成)
		JLabel label3 = new JLabel();
		label3.setText("在线情况:");
		label3.setBounds(580, 0, 100, 30);
		this.add(label3);

		
		pane3 = new JTextPane();
		pane3.setEditable(false);
		JScrollPane jsp3 = new JScrollPane(pane3);
		jsp3.setBounds(580, 30,200, 420);
		jsp3.setAutoscrolls(true);
		this.add(jsp3);
		
		this.setResizable(false);
		this.setVisible(true);

	}
	
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		if (command.equals("连接")) {
			try {
				// 和服务器建立连接
				socket = new Socket("127.0.0.1", 9090);//利用IP地址和端口号,来连接正在运行的服务器
				OutputStream ops = socket.getOutputStream();//通过socket对象获得输出流
				// 包装成缓冲字符流
				OutputStreamWriter osr = new OutputStreamWriter(ops);
				bout = new BufferedWriter(osr);
				InputStream ips = socket.getInputStream();
				InputStreamReader isr = new InputStreamReader(ips);
				 br = new BufferedReader(isr);
				
				 // 创建一个接受消息的线程,用来接受服务端发来的消息(把需要用到的参数传过去)
				ReceiveThread rt = new ReceiveThread(br, pane,jt,pane3);
				rt.start();
				
				JOptionPane.showMessageDialog(null, "连接成功");
				btn1.setText("已连接");
				btn1.setEnabled(false);//设置点击连接后,连接按钮显示为不可以点击
			//	bout.write(jt.getText()+".929144493");//把名字发出去

			} catch (Exception ef) {
				JOptionPane.showMessageDialog(null, "连接失败");
			}
		} else if (command.equals("发送")) {
			// 获得输入框中输入的消息内容
			String msg = area.getText();
			if (msg == null || msg.equals("")) {
				JOptionPane.showMessageDialog(null, "必须输入消息内容!");
			} else {
				try {
					if(!jt.getText().equals("")){
						//获取名字和需要发送的信息,一起发送出去
						bout.write(jt.getText()+" say:"+msg + "\r\n");
					}else{
						//没有名字的话,就获取IP地址和需要发送的信息,一起发送出去
						bout.write(socket.getLocalAddress()+" 说:"+msg + "\r\n");
					}
					bout.flush();
					area.setText("");//清空发送框
				} catch (Exception ef) {
					ef.printStackTrace();
				}

			}

		}
	
	}

}

 

当我们连接上服务端的时候,我们就新建一个线程类来接收服务端发来的消息(也就是服务端广播的消息),并且我们利用这个线程类来改变我们聊天界面的文字显示;

 

package 聊天室客户端;


import java.io.BufferedReader;

import javax.swing.JTextField;
import javax.swing.JTextPane;

/**
 * 客户端接收消息的线程
 * 
 * @author kowloon
 * 
 */
public class ReceiveThread extends Thread {

	private BufferedReader br;
	private JTextPane pane;// 显示消息的文本框
	private JTextField jt;
	private JTextPane pane3;
 	public ReceiveThread(BufferedReader br, JTextPane pane,JTextField jt,JTextPane pane3) {
		this.br = br;
		this.pane = pane;
		this.jt=jt;
		this.pane3=pane3;
	}

	@Override
	public void run() {
		try {
			while (true) {//只要一创建,就一直在运行
				// 读取到一个字符串
				String msg = br.readLine() +"\r\n";//读取服务器广播过来的信息
//				int i=msg.indexOf(".");
//				String panduan=msg.substring(i,i+10);
//				if(panduan.equals(".929144493")){
//					//传名字
//					String name=msg.substring(0,i);
//					pane3.setText(pane3.getText()+name+"\r\n");
//					System.out.println("名字收到!");
//				}else{//信息
					String text = pane.getText();//获得我自己的聊天框里面的信息
					pane.setText(text + msg);//把信息添加到聊天框里面,不需要换行符,因为读取数据的时候已经有了换行符
				//	System.out.println("信息收到");
			//	}
			}

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

}

 

 

 

 

 

 

 

 

 

 下面还有一些运行时候的图片,还有所有完整的项目压缩包!

 

 

 

 

 

 

  • 大小: 43.6 KB
  • 大小: 66 KB
  • 大小: 85.5 KB
  • 大小: 54.7 KB
  • 大小: 32.3 KB
  • 大小: 26 KB
  • 大小: 54.7 KB
分享到:
评论
1 楼 wangyunhom 2016-09-06  

相关推荐

    Java网络编程 TCP协议 聊天室

    在这个聊天室项目中,我们将探讨如何利用Java实现基于TCP协议的聊天室应用。 首先,TCP协议是一种面向连接的、可靠的传输协议。它在数据传输前会先建立连接,并通过三次握手来确保双方都可以正常通信。在数据传输...

    用C++基于UDP_TCP实现聊天室,文件传输功能

    用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件...

    qt TCP网络编程与聊天室的实现

    在实现聊天室应用时,通常会有一个服务器端(QTcpServer)负责接收多个客户端(QTcpSocket)的连接请求。每个新连接都会分配一个独立的QTcpSocket来处理通信。服务器端可以监听所有客户端的连接,当接收到消息时,...

    用C++基于UDP_TCP实现聊天室,文件传输功能.zip

    在这个项目中,我们主要关注的是如何使用C++编程语言来实现基于UDP和TCP协议的聊天室及文件传输功能。在实际的网络编程中,UDP(User Datagram Protocol)和TCP(Transmission Control Protocol)是两种常见的传输层...

    基于linux的TCP网络聊天室设计与实现

    【基于Linux的TCP网络聊天室设计与实现】是一个项目,旨在构建一个能在多个客户端之间进行实时通信的系统,尤其强调私聊和群聊功能。在Linux操作系统环境下,TCP(传输控制协议)因其可靠性和面向连接的特性,成为...

    QT下基于TCP的聊天室实现

    在本文中,我们将深入探讨如何在QT环境下使用TCP(传输控制协议)来实现一个简单的聊天室。QT是一个跨平台的应用程序开发框架,广泛用于创建图形用户界面和其他软件。TCP是互联网上常用的一种面向连接的、可靠的传输...

    java基于TCP的聊天室

    Java基于TCP的聊天室是一个利用Java编程语言实现的网络通信应用,主要利用了TCP(传输控制协议)来保证数据的可靠传输。在这个项目中,包含了服务器端程序和客户端程序两个核心部分,允许用户通过网络进行实时的文字...

    qt实现的tcp网络聊天室

    qt实现的tcp网络聊天室

    基于TCP的聊天室(Java实现)

    - **网络编程**:Java的`java.net`包提供了Socket类,用于创建TCP连接并进行数据交换,是实现聊天室通信的核心。 3. **聊天室架构**: - **服务器端**:服务器端程序负责监听客户端的连接请求,一旦有新的连接,...

    基于Linux的TCP多人聊天室

    C语言编写,采用CS模型,TCP、UDP网络协议实现的内网多人聊天室。 服务器:采用多线程以及线程锁处理客户端的所有请求以及信息转发任务。服务端实时显示客户的登录与登出信息;保存客户上传的共享文件(网盘功能);...

    基于TCP的聊天室的简单实现

    本项目“基于TCP的聊天室的简单实现”正是利用了TCP协议来构建一个局域网内的多人聊天平台。在这个项目中,开发者通过Socket接口在Win32环境下实现了客户端和服务器端的通信。 首先,我们来看TCP协议的基础知识。...

    TCP-chat.zip_TCP异步_TCP聊天室_TCP聊天室 异步_tcp_tcp网络聊天室

    在TCP聊天室的实现中,我们通常会利用TCP的特性来保证数据的有序性和完整性,使得在网络环境中进行实时聊天成为可能。 在TCP聊天室的设计中,首要的任务是建立客户端与服务器之间的连接。TCP通过三次握手来建立连接...

    基于Qt实现的TCP聊天室

    【标题】基于Qt实现的TCP聊天室 在IT领域,开发一个基于Qt的TCP聊天室是一项常见的实践,它涉及到客户端-服务器通信模型、网络编程以及用户界面设计等多个方面。Qt是一个跨平台的C++库,提供了丰富的功能,使得...

    聊天室TCP编程实现

    在实现TCP聊天室的过程中,主要涉及以下关键步骤: 1. **创建套接字**:使用`socket()`函数创建套接字,它是TCP通信的基础。 2. **绑定**:使用`bind()`函数将套接字与特定的IP地址和端口号关联,以便接收连接请求...

    TCP/IP实现 简易聊天室 C++

    【TCP/IP实现 简易聊天室 C++】 在计算机网络中,TCP/IP协议族是互联网通信的基础。这个简易聊天室项目就是基于TCP/IP协议,使用C++编程语言实现的,旨在展示如何创建一个基本的客户端-服务器通信系统。在这个系统...

    基于TCP的网络聊天室的设计(一步一步教你CSocket网络编程)

    本系统能实现基于VC++的网络聊天室系统。有单独的客户端、服务器端。 服务器应用程序能够接受来自客户端的广播,然后向客户端发送本机的IP与服务端口,让客户端接入到服务器进行聊天,检测用户名是否合法(重复),...

    java基于TCP/IP的聊天室

    Java基于TCP/IP的聊天室是一种实现用户间实时通信的应用程序,它依赖于网络协议TCP/IP进行数据传输。在这个系统中,通常包含两个主要组件:服务器端和客户端。 **TCP/IP协议**是Transmission Control Protocol/...

    Python实现的多人聊天室源码,基于socket tcp通信,使用tkinter做客户端界面,含可执行文件

    在本项目中,我们探讨的是一个使用Python编程语言实现的多人聊天室,它基于socket TCP通信协议,并且利用Tkinter库构建了用户友好的客户端界面。这个聊天室系统允许多个用户同时在线交流,增强了实时互动性。以下是...

Global site tag (gtag.js) - Google Analytics