基于多线程、Socket套接字实现点对点两人聊天

1、实现效果

QQ服务端:
基于多线程、Socket套接字实现点对点两人聊天_第1张图片

QQ用户端:基于多线程、Socket套接字实现点对点两人聊天_第2张图片

2、服务端代码

(1)客户端界面代码 以及实现发送功能

package com.wyl.www;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class QQServerSystem {
	private JFrame frame; // 窗口
	private Container container; // 创中的容器对象

	public JTextArea txtList = null; // 文本列表框
	public JTextField txtMsg = null; // 文本发送框
	public JButton btn = null; // 发送按钮

	public String addmsg = "listening";
	
	public OutputStream os; //用于发送信息。

	public QQServerSystem() {
		frame = new JFrame("小明的QQ服务端");
		frame.setBounds(400, 300, 800, 600); // 设置窗口大小和位置
		frame.setLayout(new BorderLayout());
		container = frame.getContentPane();

		txtList = new JTextArea(5, 20);
		container.add(txtList, BorderLayout.CENTER);
		
		JPanel txtPanel = new JPanel();
		txtPanel.setLayout(new FlowLayout(FlowLayout.LEADING));
		txtMsg = new JTextField(60);
		btn = new JButton("发送");

		btn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				// 获取文本框值
				System.out.println("Send Btn click...");
				String str = txtMsg.getText();
				try {
					os.write(str.getBytes());
					os.flush();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				addmsg = "server:" + str;
				refreshMsglist();
				txtMsg.setText("");
			}
		});

		txtPanel.add(txtMsg);
		txtPanel.add(btn);
		container.add(txtPanel, BorderLayout.SOUTH);
		startSeverThread();
		refreshMsglist();
	}

	public void startSeverThread() {
		new ServerListenThread(this).start();
	}

	public void refreshMsglist() {
		String str = txtList.getText();
		txtList.setText(str + addmsg + "\n");
	}

	public void start() {
		frame.setVisible(true);
	}

}

(2)ServerListenThread 多线程类 实现run方法,该线程用于监听8888端口,接受数据并显示

package com.wyl.www;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerListenThread extends Thread {
	
	public QQServerSystem qqs;

	public ServerListenThread(QQServerSystem qqs) {
		super();
		this.qqs = qqs;
	}

	@Override
	public void run() {
		try {
			ServerSocket ss = new ServerSocket(8888);
			System.out.println("listening 8888...");
			Socket client = ss.accept();// 这个方法是阻塞的,也就是说有人连接时才会向下进行
			InputStream is = client.getInputStream();
			qqs.os = client.getOutputStream();

			byte[] b = new byte[1024];
			int i = 0;
			while(i < 1000){
				int len = is.read(b);
				String str = new String(b, 0, len);
				System.out.println("Received:" + str);
				qqs.addmsg = "client:"+str;
				qqs.refreshMsglist();
				i++;
			}
			
			is.close();
			ss.close();
		} catch (Exception e) {
			System.out.println("Server failed!");
		}

	}
}

(3)编写ServerMain方法

package com.wyl.www;

public class ServerMain {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		QQServerSystem qs = new QQServerSystem();
		qs.start();
	}
}
 

3、用户端代码

(1)用户端界面 ClientSystem

package com.wyl.www;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;


public class QQClientSystem {
	private JFrame frame;		//窗口
	private Container container;	//创中的容器对象
	
	public JTextArea txtList=null;	//文本列表框
	public JTextField txtMsg=null;	//文本发送框
	public JButton btn=null;		//发送按钮
	
	public String addmsg = "connecting";
	
	public OutputStream os; //用于发送信息。
	
	public QQClientSystem() {
		frame = new JFrame("小明的QQ客户端");
		frame.setBounds(400, 300, 800, 600); // 设置窗口大小和位置
		frame.setLayout(new BorderLayout());
		container = frame.getContentPane();
		
		txtList = new JTextArea(5, 20);
		container.add(txtList, BorderLayout.CENTER);
		
		JPanel txtPanel = new JPanel();
		txtPanel.setLayout(new FlowLayout(FlowLayout.LEADING));
		txtMsg = new JTextField(60);
		btn = new JButton("发送");
		
		btn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				//获取文本框值
				System.out.println("Send Btn click...");
				String str = txtMsg.getText();
				try {
					os.write(str.getBytes());
					os.flush();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				addmsg = "client:" + str;
				refreshMsglist();
				txtMsg.setText("");
			}
		});
		
		txtPanel.add(txtMsg);
		txtPanel.add(btn);
		container.add(txtPanel, BorderLayout.SOUTH);
		startRequestThread();
		refreshMsglist();
	}
	
	public void startRequestThread() {
		new ClientRequestThread(this).start();
	}
	
	public void refreshMsglist(){
		String str = txtList.getText();
		txtList.setText(str + addmsg + "\n");
	}

	public void start(){
		frame.setVisible(true);
	}

}

(2)ClientRequestThread 多线程类,实现run方法,实现连接服务器端,用于接收服务器发送的消息

	package com.wyl.www;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ClientRequestThread extends Thread {
	
	public QQClientSystem qqc;

	public ClientRequestThread(QQClientSystem qqc) {
		super();
		this.qqc = qqc;
	}

	@Override
	public void run() {
		try {
			Socket s = new Socket("localhost",8888);
			qqc.addmsg = "connected server.";
			qqc.refreshMsglist();
			
			InputStream is = s.getInputStream();
			qqc.os = s.getOutputStream();
			String str = "hello";
			
			byte[] b = new byte[1024];
			int i = 0;
			while(i < 1000){
				int len = is.read(b);
				str = new String(b, 0, len);
				System.out.println("Received:" + str);
				qqc.addmsg = "server:" + str;
				qqc.refreshMsglist();
				i++;
			}
			
			System.out.println("send msg.");
			s.close();
		} catch (IOException e) {
			System.out.println("conection faild!");
		}

	}
}


(3)main方法

package com.wyl.www;

public class ClientMain {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		QQClientSystem qs = new QQClientSystem();
		qs.start();
	}
}

你可能感兴趣的:(基于多线程、Socket套接字实现点对点两人聊天)