一个简易的简易聊天程序

目录

问题描述:

配置环境:

目录结构:

UML类图分析:

效果展示:

代码: 

参考资料:


问题描述:

编写一个简易的套接字通信的简易聊天程序,要求:程序的界面必须是GUI,服务端必须以多线程的方式处理客户请求。

配置环境:

eclipse、Java8

目录结构:

            

UML类图分析:

 

效果展示:

 

 

代码: 

        Chat是主窗口,通过登录来确定姓名和密码(姓名用来作为交流代号,密码未设置用处)

        Client是客户端,每个Chat可以触发一次客户端

        Sever是服务器端,端口号固定,每次连接不同的客户端相当于开启不同的线程       

        SeverThread是服务端开启的线程,控制不同客户端的信息

        在该程序中,是通过主窗口来调用不同的客户端,通过客户端连接服务器的一条新线程,来进行信息的传递

         而在每个客户端之间进行的信息的展示是通过重写每次的信息来达到信息的交流完整。

// Chat.java

package gui4_2_2;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class Chat {
	static JTextField jtext0,jtext1;
	static JButton jb0;
	static String jt0,jt1;
	
	public static void main(String[] args) {
		JFrame jf = new JFrame("登录聊天室");
		jf.setSize(300, 300);
		jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

	    JPanel jp0 = new JPanel(new FlowLayout(FlowLayout.CENTER));
	    jp0.add(new JLabel("请输入名字:"));
		jtext0 = new JTextField(10);
	    jp0.add(jtext0);

	    JPanel jp1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
	    jp1.add(new JLabel("请输入密码:"));
	    jtext1 = new JTextField(10);
	    jp1.add(jtext1);
	    
	    // 第 3 个 JPanel, 使用浮动布局, 并且容器内组件居中显示
	    JPanel jp2 = new JPanel(new FlowLayout(FlowLayout.CENTER));
	    jb0 = new JButton("确认进入聊天室");
	    jp2.add(jb0);
	    
	    jb0.addActionListener(new ActionListener() {
		    public void actionPerformed(ActionEvent e) {
		    	jt0 =jtext0.getText();
		    	jt1=jtext1.getText();
		    	System.out.println(Integer.valueOf(jt1).intValue());
		    	if(Integer.valueOf(jt1).intValue()<10000) {
		    		JOptionPane.showMessageDialog(null, "密码少于5位哦!");
		    	}else{
			    	new Client(jt0);
		    	}
		    }
		});
	    
	    // 创建一个垂直盒子容器, 把上面 3 个 JPanel 串起来作为内容面板添加到窗口
	    Box vBox = Box.createVerticalBox();
	    vBox.add(jp0);
	    vBox.add(jp1);
	    vBox.add(jp2);

	    jf.setContentPane(vBox);

//	    jf.pack();
	    jf.setLocationRelativeTo(null);
	    jf.setVisible(true);
	}
}
// Client.java

package gui4_2_2;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client extends JFrame implements Runnable{
	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	JTextArea textArea;//显示信息的文本区
	Socket socket;
	private  String name;
	public Client(String name){
		this.name = name;
		try {
			socket = new Socket("localhost",9999);
		} catch (IOException e) {
			e.printStackTrace();
		}
		loadframe();
		new Thread(this).start();//开启接受消息的线程
	}

	public void loadframe() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 733, 400);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		textArea = new JTextArea();
		textArea.setEditable(false);
		textArea.setBounds(10, 10, 697, 276);
		contentPane.add(textArea);
		
		JTextArea textArea_1 = new JTextArea();
		textArea_1.setBounds(10, 296, 565, 50);
		contentPane.add(textArea_1);
		
		JButton btn0 = new JButton("发送");
		btn0.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				sendmessage(textArea_1.getText());
				textArea_1.setText(null);
			}
		});
		btn0.setBounds(580, 310, 97, 23);
		contentPane.add(btn0);
		setVisible(true);
	}
	public void run(){
		while (true){
			acceptmessage();
		}
	}
	public void sendmessage(String message){
		try {
			OutputStream write = socket.getOutputStream();
			write.write((name+"说: "+message).getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void acceptmessage(){
		String message=null;
		try {
			InputStream read = socket.getInputStream();			
			byte[] bytes = new byte[1024];
			while (read.read(bytes)!=-1){
				message = new String(bytes);
				bytes = new byte[1024];
				System.out.println(message);
				textArea.setText(textArea.getText()+"\n"+message);
			}
			textArea.setText(textArea.getText()+"\n"+message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
//	public static void main(String[] args) {
//		new Client();
//	}
}

//Sever.java

package gui4_2_2;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

public class Sever implements Runnable{

    ArrayList<Socket> sockets = new ArrayList<>();
    int port;
    ServerSocket socket;
    public Sever() {
    }

    public Sever(int port) {
        this.port = port;
        try {
            System.out.println("服务器ip"+InetAddress.getLocalHost()+"\n服务器端口号"+port);
            try {
                socket = new ServerSocket(port);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public void run(){
        while (true){
            try {
                Socket accept = socket.accept();
                synchronized (accept){
                    sockets.add(accept);
                }
                System.out.println(accept);
                Thread t = new Thread(new SeverThread(accept,sockets));
                t.start();
            } catch (IOException e) {
            }
        }
    }
    public static void main(String[] args) {
        new Thread(new Sever(9999)).start();
    }
}

// SeverThread.java

package gui4_2_2;

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

public class SeverThread extends Sever{
    Socket socket;
    public SeverThread(Socket socket,ArrayList<Socket> sockets) {
        this.socket = socket;
        super.sockets = sockets;
    }

    public void run(){
        while (true)
            accepmessage();
    }

    public void accepmessage() {
        try {
            InputStream reader = socket.getInputStream();
            String acceptmessage=String.valueOf(socket.getPort());

            byte[] bytes = new byte[1024];
            int len;
            while ((len=reader.read(bytes) )!= -1) {
//                acceptmessage="端口号为"+String.valueOf(socket.getPort())+"发送的信息: ";
            	acceptmessage="";
                acceptmessage += new String(bytes,0,len);
                sendmessage(acceptmessage);
                bytes = new byte[1024];
                System.out.println(acceptmessage);
            }
        } catch (Exception e) {
            try {
                socket.close();
            } catch (IOException ioException) {
            }
            sockets.remove(socket);
        }
    }
    public void sendmessage(String message){
        OutputStream write1 = null;
        for (Socket socket1 : sockets) {
            try {
                write1 = socket1.getOutputStream();
                write1.write(message.getBytes());
            } catch (IOException e) {
            }
        }
    }
}

参考资料:

(97条消息) Java Swing 图形界面开发(目录)_xietansheng的博客-CSDN博客_swing

(97条消息) JavaTCP协议实现多线程模式多人聊天,开启服务端后,只需要开启多个客户端的类,就可以进行多人聊天了,Java网络编程_程东南的博客-CSDN博客_java tcp 多线程

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这里给出一个简单的Python socket聊天程序的代码: 服务端: ```python import socket # 创建socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP和端口 server_socket.bind(('0.0.0.0', 9999)) # 开始监听 server_socket.listen(5) # 等待客户端连接 print('等待客户端连接...') client_socket, addr = server_socket.accept() print('客户端已连接,地址为:', addr) while True: # 接收客户端消息 recv_msg = client_socket.recv(1024).decode('utf-8') print('客户端:', recv_msg) # 发送消息给客户端 send_msg = input('我:') client_socket.send(send_msg.encode('utf-8')) ``` 客户端: ```python import socket # 创建socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务端 client_socket.connect(('127.0.0.1', 9999)) while True: # 发送消息给服务端 send_msg = input('我:') client_socket.send(send_msg.encode('utf-8')) # 接收服务端消息 recv_msg = client_socket.recv(1024).decode('utf-8') print('服务端:', recv_msg) ``` 运行服务端和客户端代码,就可以进行聊天了。注意,这个是单向聊天,需要在服务端和客户端分别输入消息。如果要实现双向聊天,可以将服务端和客户端的代码合并,并且在发送消息后接收对方的回复。 ### 回答2: 以下是一个简单的socket聊天程序的代码实现: ```python # 服务器端代码 import socket def server_program(): # 创建一个socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取主机名 host = socket.gethostname() port = 12345 # 设置监听的端口号 # 绑定主机名和端口号 server_socket.bind((host, port)) # 监听连接 server_socket.listen(1) print("等待客户端连接...") # 接受客户端连接 client_socket, address = server_socket.accept() print("连接来自: " + str(address)) while True: # 接收消息 data = client_socket.recv(1024).decode() print("收到消息: " + data) # 如果客户端发送的消息是"退出",则关闭连接 if data == "退出": break # 发送回复消息 message = input("回复消息: ") client_socket.send(message.encode()) # 关闭连接 client_socket.close() if __name__ == '__main__': server_program() ``` ```python # 客户端代码 import socket def client_program(): # 创建一个socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 获取服务器的主机名和端口号 host = socket.gethostname() port = 12345 # 连接服务器 client_socket.connect((host, port)) while True: # 发送消息 message = input("发送消息: ") client_socket.send(message.encode()) # 接收回复消息 data = client_socket.recv(1024).decode() print("收到回复: " + data) # 如果发送的消息是"退出",则断开连接 if message == '退出': break # 关闭连接 client_socket.close() if __name__ == '__main__': client_program() ``` 此聊天程序是基于TCP协议的socket通信实现的。首先,服务器端通过`socket.bind()`绑定主机名和监听的端口号,然后通过`socket.listen()`开始监听客户端的连接。当客户端连接成功后,服务器端通过`socket.accept()`接受客户端的连接请求,并打印连接来自哪个地址。 在循环中,服务器端接收客户端发送的消息,如果收到的消息是"退出",则断开连接;否则,服务器端通过`input()`获取回复消息,并通过`socket.send()`发送给客户端。 客户端通过`socket.connect()`连接服务器,同样也在循环中,首先通过`input()`发送消息给服务器端,然后通过`socket.recv()`接收服务器端的回复消息。如果发送的消息是"退出",则断开连接。 以上即为简易socket聊天程序的代码实现。 ### 回答3: 以下是一个简易的Socket聊天程序的代码示例: ```python # 服务器端代码 import socket # 创建一个TCP/IP socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定服务器地址和端口 server_address = ('localhost', 12345) server_socket.bind(server_address) # 监听连接 server_socket.listen(1) print("等待客户端连接...") # 等待一个客户端连接 client_socket, client_address = server_socket.accept() print("已连接客户端:", client_address) while True: try: # 接收客户端发送的消息 data = client_socket.recv(1024).decode() if not data: break print("收到客户端消息:", data) # 回复消息给客户端 response = "服务器收到消息:" + data client_socket.sendall(response.encode()) except Exception as e: print("发生错误:", str(e)) break # 关闭连接 client_socket.close() server_socket.close() # 客户端代码 import socket # 创建一个TCP/IP socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 服务器地址和端口 server_address = ('localhost', 12345) # 连接到服务器 client_socket.connect(server_address) print("已连接服务器:", server_address) while True: try: # 向服务器发送消息 message = input("请输入消息:") client_socket.sendall(message.encode()) # 接收服务器回复的消息 response = client_socket.recv(1024).decode() print("收到服务器消息:", response) except KeyboardInterrupt: print("聊天结束.") break # 关闭连接 client_socket.close() ``` 以上代码是一个简单的基于TCP/IP协议的Socket聊天程序程序运行时,服务器端先绑定地址和端口,并等待客户端连接。客户端连接到服务器后,可以输入消息发送给服务器,服务器收到消息后会发送回复给客户端。客户端接收到回复后再次发送消息,如此往复,直到通过键盘中断退出聊天
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值