基于Java的tcp实现文本聊天系统

来源:互联网 发布:java报表 编辑:程序博客网 时间:2024/06/04 20:14

基于Java的tcp实现简单文本聊天

一:在看本篇之前,请先了解tcp协议;这里就不再介绍了。
整个过程的实现:
1. Server端:ServerSocket初始化,监听8888端口(可以理解为一直等着取水);accept一个客户端之后,把它交给一个客户端处理,并且开启一个线程处理(取到水之后,交给另外一个人,由它处理这些水,而自己只负责取水);代码如下:
Server:
package com.wolf.server.net;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;


public class ChatServer {


private ServerSocket ss = null;
private boolean bStart = false; 

private List<Client> clients  = new ArrayList<Client>();

public ChatServer() {
// 构造方法
try {
ss = new ServerSocket(8888);
bStart = true;
} catch(SocketException e) {
System.out.println("商品使用中, 请关闭相关程序, 并重新运行。。。。。。");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
start();
}

public void start() {
// 开始连接客户端
try {
while(bStart) {
Socket s = ss.accept();
System.out.println("a client connected"); // 调试语句
Client c = new Client(s);
clients.add(c);
new Thread(c).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}


// ***********************************************************************************
public static void main(String[] args) {
new ChatServer();
}

private class Client implements Runnable {
// 客户端

private Socket s = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;

private boolean bConected = false;

public Client(Socket s) {
// 构造方法

try {
this.s = s;
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConected = true;
} catch (IOException e) {
e.printStackTrace();
}
}

public void sent(String str) {
// 发送信息
try {
if(str != null) {
dos.writeUTF(str);
}

} catch(SocketException e) {
System.out.println("client已退出"); //调试语句
bConected = false;
close();
} catch (IOException e) {
e.printStackTrace();
}
}

public String read() {
// 读取信息
String str = null;
try {
str = dis.readUTF();
} catch(SocketException e) {
//System.out.println("对方已退出"); //调试语句
bConected = false;
close();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}

public void close() {
// 关闭资源 , 节省内存
try {
if(dis != null) {
dis.close();
dis = null;
}
if(dos != null) {
dos.close();
dos = null;
}
if(s != null) {
s.close();
s = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}


@Override
public void run() {
while(bConected) {
for(int i = 0; i < clients.size(); i ++) {
Client c = clients.get(i);
if(c != this) {
//System.out.println(read()); // 调试语句
String str = read();
if(str != null) {
c.sent(str);
}

}
}
}
close();
}
}
}


2. Client 端:client端一上来就连接Server(可以理解为一个管道伸到Server), 连接成功之后,我们就开始包装这个管道,并开启一个线程在那等着接收Server发来的信息,并且如果自己想发信息,就调用sent;
说了这么多,还不如直接看代码,

Client

package com.wolf.client;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


import com.wolf.client.net.ConnectedServer;


public class ChatClient extends JFrame{


public static final int WIDTH = 400;
public static final int HEIGHT = 600;

private JPanel mainPanel = null;

private JTextArea taInput = null;
private JTextArea taOutput = null;

private ConnectedServer connectedServer = null;

public ChatClient() {
// 构造方法
this.setSize(WIDTH, HEIGHT);
this.setLocation(200, 80);
this.setTitle("wolvesqun");

launchFrame();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setVisible(true);
connectedServer = new ConnectedServer(this);
Thread t = new Thread(new TaOutputListener());
t.start();
}

public void launchFrame() {
// 主窗口
mainPanel = (JPanel)this.getContentPane();
mainPanel.setLayout(null);
mainPanel.setBackground(Color.green);

// 输出窗口
taOutput = new JTextArea();
taOutput.setBounds(-2, -2, 800, 400);
taOutput.setFont(new Font("楷体", Font.BOLD, 25));
taOutput.setForeground(Color.blue);
taOutput.setBackground(new Color(200, 237, 204));
//taOutput.setBorder(BorderFactory.createLoweredBevelBorder());

JScrollPane scrollTaOutputPanel = new JScrollPane(taOutput); //
scrollTaOutputPanel.setBounds(-2, -2, 800, 400);
//scrollTaOutputPanel.add(taOutput);
mainPanel.add(scrollTaOutputPanel);

// 输入窗口
taInput = new JTextArea();
taInput.setBounds(0, 450, 800, 111);
taInput.setBackground(new Color(200, 237, 204));
taInput.setFont(new Font("楷体", Font.BOLD, 25));
taInput.addKeyListener(new TaInputListener());
mainPanel.add(taInput);
}

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

private class TaInputListener extends KeyAdapter {
// 输入框键盘事件
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
//System.out.println("KeyCode = " + KeyEvent.VK_ENTER); // 调试语句
if(key == KeyEvent.VK_ENTER) {
String strInput = taInput.getText().trim();
if(!strInput.equals("")){
taOutput.append(strInput + '\n');
taInput.setText("");
connectedServer.sent(strInput);
}
}
}


}

private class TaOutputListener implements Runnable {
// 输出框事件

private boolean bConnected = false;

public TaOutputListener() {
bConnected = true;
}

@Override
public void run() {
while(bConnected) {
String str = connectedServer.read();
taOutput.append(str + '\n');
}
}
}
}


效果图如下:



这里在多说一句:本次实现的是聊天群功能,至于点对点聊天,我想就不用说了,看完理解这里面的代码,你就会了。
下一篇我将实现IOS连接到服务器,并实现聊天功能(代码会在写完 ios 再一起提供)。
















1 0
原创粉丝点击