学习java一段时间了,今天写来一个即时通信的小例子练手在其过程中也学到了一些知识拿出来和大家分享,请路过的各位大神多多赐教。。。
好了下面讲一下基本的思路:
首先,编写服务器端的程序,简单点说吧就是在服务上开启一个线程循环等待客户端的连接,为每一个连接到服务器的Socket 创建一个实例存放在集合中,然后使用InputSteam读取从客户端发过来的数据然后转发给除自己之外的所有的客户端
然后是客户端,首先开启一个线程连接都服务器端,循环监听服务器发送回来的数据
这里要说一下为了明确是谁发出的消息我在这里采用了JSON的数据格式进行消息的传递在客户端对服务器端的数据进行JSON格式的解析显示到文本区
下面贴出客户端的源码(这里没有进行分包请大家谅解):
package com.chact; import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException; import javax.swing.JOptionPane; import org.json.JSONException;
import org.json.JSONObject; @SuppressWarnings("serial")
public class ChactClient extends Frame { /**
* 定义所有要使用的成员变量。
*
*/
public String Other = null;
public Button mButton = new Button("使用名称");
public static TextField mTextField = new TextField(20);
public static TextField usernameTextField = new TextField(20);
public static TextArea mTextArea = new TextArea(30, 30);
public static Boolean Flag;
Socket socket = null;
static StringBuffer stringBuffer = new StringBuffer();
public static Socket s = null;
OutputStream outputStream = null;
OutputStreamWriter writer = null;
static String ChactContent = null; /**
*
* 定义的主方法
*
* @param args
* @throws UnknownHostException
* @throws IOException
*/ public static void main(String[] args) throws UnknownHostException, IOException { new ChactClient().launchFrame(); /**
* 开启一个新的线程用来连接到服务器端
*/ Thread mThread = new Thread() {
@Override
public void run() {
try {
s = new Socket("123.206.76.188", 12345);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/********************************************************************************/
/**
*
* 循环的从服务器读取数据
*
*/
while (true) { try {
InputStream iso = s.getInputStream();
InputStreamReader sior = new InputStreamReader(iso, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(sior);
String string; while ((string = bufferedReader.readLine()) != null) {
System.out.println(string); // 这里使用JSON数据格式进行数据的传递 JSONObject jsonObject = new JSONObject(string); // 如果数据是自己发送的就不必再进行读取和显示
if (!jsonObject.getString("username").equals(usernameTextField.getText().trim())) { mTextArea.append(jsonObject.getString("username") + ": "
+ jsonObject.getString("Content") + "\n");
mTextArea.setForeground(Color.CYAN);
stringBuffer = null;
} else {
stringBuffer = null;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } } };
mThread.start(); } /****************************************************************************/
/**
*
* 定义可见的窗口
*
* @throws UnknownHostException
* @throws IOException
*/ public void launchFrame() throws UnknownHostException, IOException {
Frame frame = new Frame();
frame.setTitle("开拓者即时聊天系统");
frame.setLocation(300, 300);
// this.setBounds(300,300,300,300);
frame.setSize(600, 800);
frame.setResizable(false); frame.add(mButton, BorderLayout.LINE_START);
frame.add(usernameTextField, BorderLayout.LINE_END);
frame.add(mTextArea, BorderLayout.NORTH);
frame.add(mTextField, BorderLayout.SOUTH);
mTextArea.setFont(new Font("微软雅黑", Font.PLAIN, 15));
frame.pack(); mTextField.addActionListener(new TFlistener());
mTextArea.setEditable(false);
mTextField.setEditable(false);
mButton.addActionListener(new ActionListener() { /**
* 首先进行用户名的读取如果为空则提示先输入用户名
*
*
*/ @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
// String Other;
Other = usernameTextField.getText().trim();
Other = Other.replace('\n', ' ');
// System.out.println(Other);
if (!Other.equals("")) { usernameTextField.setEditable(false);
mTextField.setEditable(true);
} else {
JOptionPane.showMessageDialog(null, "昵称不能为空!", "标题", JOptionPane.INFORMATION_MESSAGE);
}
}
}); /**
*
* 定义关闭窗口的的事件监听器
*
*/ frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) { // 提示对方下线的JSON数据 String JSON = "{" + "'username'" + ":" + Other + ',' + "'Content'" + ":" + "已下线!!!" + "}"; try {
outputStream = socket.getOutputStream();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
writer = new OutputStreamWriter(outputStream, "UTF-8");
} catch (UnsupportedEncodingException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
writer.write(JSON + "\n");
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
writer.flush();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
System.exit(0);
try {
socket.close();
destory();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
frame.setVisible(true); // 获取与服务器的连接 Contection(); } /**
*
* 定义与服务器连接的函数
*
* @throws UnknownHostException
* @throws IOException
*/
public void Contection() throws UnknownHostException, IOException { socket = new Socket("123.206.76.188", 12345);
System.out.println("成功连接到客户端");
} /**
*
* 监听回车键进行数据的发送的监听器
*
*
* @author Administrator-SYSTEM
*
*/ private class TFlistener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
ChactContent = mTextField.getText().trim();
try { String JSON = "{" + "'username'" + ":" + Other + ',' + "'Content'" + ":" + ChactContent + "}";
outputStream = socket.getOutputStream();
writer = new OutputStreamWriter(outputStream, "UTF-8");
writer.write(JSON + "\n");
writer.flush();
mTextArea.setForeground(Color.BLACK);
mTextArea.append("我说: " + ChactContent + "\n");
mTextField.setText("");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} }
// 进行资源的释放 public void destory() throws IOException { outputStream.close();
writer.close();
socket.close(); } }