我们在写一个聊天室的小项目时候,需要有客户端和服务器端;并且他们必须分开开发,不能有任何互相调用的语句出现!(并且运行的时候先运行服务端(只能一个),然后可以运行多个客户端)
一般我们先写好服务端:
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(); } } }
下面还有一些运行时候的图片,还有所有完整的项目压缩包!
相关推荐
在这个聊天室项目中,我们将探讨如何利用Java实现基于TCP协议的聊天室应用。 首先,TCP协议是一种面向连接的、可靠的传输协议。它在数据传输前会先建立连接,并通过三次握手来确保双方都可以正常通信。在数据传输...
用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件...
在实现聊天室应用时,通常会有一个服务器端(QTcpServer)负责接收多个客户端(QTcpSocket)的连接请求。每个新连接都会分配一个独立的QTcpSocket来处理通信。服务器端可以监听所有客户端的连接,当接收到消息时,...
在这个项目中,我们主要关注的是如何使用C++编程语言来实现基于UDP和TCP协议的聊天室及文件传输功能。在实际的网络编程中,UDP(User Datagram Protocol)和TCP(Transmission Control Protocol)是两种常见的传输层...
【基于Linux的TCP网络聊天室设计与实现】是一个项目,旨在构建一个能在多个客户端之间进行实时通信的系统,尤其强调私聊和群聊功能。在Linux操作系统环境下,TCP(传输控制协议)因其可靠性和面向连接的特性,成为...
在本文中,我们将深入探讨如何在QT环境下使用TCP(传输控制协议)来实现一个简单的聊天室。QT是一个跨平台的应用程序开发框架,广泛用于创建图形用户界面和其他软件。TCP是互联网上常用的一种面向连接的、可靠的传输...
Java基于TCP的聊天室是一个利用Java编程语言实现的网络通信应用,主要利用了TCP(传输控制协议)来保证数据的可靠传输。在这个项目中,包含了服务器端程序和客户端程序两个核心部分,允许用户通过网络进行实时的文字...
qt实现的tcp网络聊天室
- **网络编程**:Java的`java.net`包提供了Socket类,用于创建TCP连接并进行数据交换,是实现聊天室通信的核心。 3. **聊天室架构**: - **服务器端**:服务器端程序负责监听客户端的连接请求,一旦有新的连接,...
C语言编写,采用CS模型,TCP、UDP网络协议实现的内网多人聊天室。 服务器:采用多线程以及线程锁处理客户端的所有请求以及信息转发任务。服务端实时显示客户的登录与登出信息;保存客户上传的共享文件(网盘功能);...
本项目“基于TCP的聊天室的简单实现”正是利用了TCP协议来构建一个局域网内的多人聊天平台。在这个项目中,开发者通过Socket接口在Win32环境下实现了客户端和服务器端的通信。 首先,我们来看TCP协议的基础知识。...
在TCP聊天室的实现中,我们通常会利用TCP的特性来保证数据的有序性和完整性,使得在网络环境中进行实时聊天成为可能。 在TCP聊天室的设计中,首要的任务是建立客户端与服务器之间的连接。TCP通过三次握手来建立连接...
【标题】基于Qt实现的TCP聊天室 在IT领域,开发一个基于Qt的TCP聊天室是一项常见的实践,它涉及到客户端-服务器通信模型、网络编程以及用户界面设计等多个方面。Qt是一个跨平台的C++库,提供了丰富的功能,使得...
在实现TCP聊天室的过程中,主要涉及以下关键步骤: 1. **创建套接字**:使用`socket()`函数创建套接字,它是TCP通信的基础。 2. **绑定**:使用`bind()`函数将套接字与特定的IP地址和端口号关联,以便接收连接请求...
【TCP/IP实现 简易聊天室 C++】 在计算机网络中,TCP/IP协议族是互联网通信的基础。这个简易聊天室项目就是基于TCP/IP协议,使用C++编程语言实现的,旨在展示如何创建一个基本的客户端-服务器通信系统。在这个系统...
本系统能实现基于VC++的网络聊天室系统。有单独的客户端、服务器端。 服务器应用程序能够接受来自客户端的广播,然后向客户端发送本机的IP与服务端口,让客户端接入到服务器进行聊天,检测用户名是否合法(重复),...
Java基于TCP/IP的聊天室是一种实现用户间实时通信的应用程序,它依赖于网络协议TCP/IP进行数据传输。在这个系统中,通常包含两个主要组件:服务器端和客户端。 **TCP/IP协议**是Transmission Control Protocol/...
在本项目中,我们探讨的是一个使用Python编程语言实现的多人聊天室,它基于socket TCP通信协议,并且利用Tkinter库构建了用户友好的客户端界面。这个聊天室系统允许多个用户同时在线交流,增强了实时互动性。以下是...