先看下效果图,一端运行在远程服务器,一端在本机电脑上运行,在局域网内两端可正常通信,由于我学校网络是局域网,所以外网ip接收得到消息,反之外网发消息过来本机收不到。不是局域网的同学理论上可以直接通信。
思路是利用Socket来收发数据。具体可看代码。
代码分为两部分,一部分为聊天窗口的绘制,一部分为事件和通信的实现,这里一起贴了出来:
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Label;
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.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Calendar;
import javax.swing.JOptionPane;
public class Chat {
public static void main(String[] args) {
new MyFrame();
new MyEvent();
Thread thread = new Thread(new MyRecevier());
thread.start();
}
}
class MySend {
public MySend() throws Exception {
DatagramSocket dSocket = new DatagramSocket(10000);
Calendar c = Calendar.getInstance();
byte[] buf = ("from IP:" + InetAddress.getLocalHost() + "\r\n" + MyEvent.myText)
.getBytes();
System.out.println("收到内容:" + MyEvent.myText);
DatagramPacket dPacket = new DatagramPacket(buf, buf.length,
InetAddress.getByName(MyEvent.myIp), 8888);// 自定义
//
// DatagramPacket dPacket=
// new DatagramPacket(buf,
// buf.length,InetAddress.getByName("192.168.56.1"),8888);//本机测试
dSocket.send(dPacket);
dSocket.close();
// 显示自己发的信息
// ----------------本机显示测试------------------//
String date = "Time:" + c.get(Calendar.YEAR) + "年"
+ (c.get(Calendar.MONTH) + 1) + "月"
+ c.get(Calendar.DAY_OF_MONTH) + "日" + c.get(Calendar.HOUR)
+ "时" + c.get(Calendar.MINUTE) + "分";
MyFrame.receField.append(date + "\r\nME:" + MyEvent.myText + "\r\n");
// MyFrame.receField.setText(date+"\r\n"+string);
// ----------------本机测试------------------//
// System.out.println(dPacket);
}
}
class MyRecevier implements Runnable {
Calendar c;
public MyRecevier() {
c = Calendar.getInstance();
}
@Override
public void run() {
DatagramSocket dSocket = null;
try {
dSocket = new DatagramSocket(8888);
} catch (SocketException e1) {
e1.printStackTrace();
}
;
byte[] buf = new byte[1024];
DatagramPacket dPacket = new DatagramPacket(buf, buf.length);
while (true) {
try {
dSocket.receive(dPacket);
} catch (IOException e) {
e.printStackTrace();
}
String string = new String(dPacket.getData(), 0,
dPacket.getLength());
// ----------------本机显示测试------------------//
String date = "Time:" + c.get(Calendar.YEAR) + "年"
+ (c.get(Calendar.MONTH) + 1) + "月"
+ c.get(Calendar.DAY_OF_MONTH) + "日" + c.get(Calendar.HOUR)
+ "时" + c.get(Calendar.MINUTE) + "分";
MyFrame.receField.append(date + "\r\n" + string + "\r\n");
// MyFrame.receField.setText(date+"\r\n"+string);
// ----------------本机测试------------------//
}
// dSocket.close();
}
}
class MyEvent {
static String myIp = "";
static String myText;
String myReceText;
public MyEvent() {
// 提交
MyFrame.btnPost.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myIp = MyFrame.ipField.getText().toString().trim();
String[] strings = myIp.split("\\.");
boolean t = true;
if (strings.length != 4) {
t = false;
JOptionPane.showMessageDialog(null, "请输入正确的IP地址!");
} else {
for (int i = 0; i < strings.length; i++) {
// 告知此字符串是否匹配给定的正则表达式。
if (!strings[i]
.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$")) {
t = false;
JOptionPane.showMessageDialog(null, "带有非数字字符!");
break;
} else if (Integer.parseInt(strings[i]) > 255
|| Integer.parseInt(strings[i]) < 0) {
t = false;
JOptionPane.showMessageDialog(null, "请输入正确的IP地址!");
break;
}
}
}
if (t) {
myIp = MyFrame.ipField.getText().toString().trim();
System.out.println("目标IP:" + myIp);
JOptionPane.showMessageDialog(null, "提交成功!");
}
}
});
// 清除
MyFrame.btnCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MyFrame.inputField.setText(" ");
}
});
// 发送并清除编辑内容
MyFrame.btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myText = MyFrame.inputField.getText().toString().trim();
if (myIp.equals("")) {
JOptionPane.showMessageDialog(null, "请输入目标IP并提交!");
} else if (myText.equals("")) {
JOptionPane.showMessageDialog(null, "请输入内容再发送!");
} else {
System.out.println("发送内容:" + myText);
MyFrame.inputField.setText(" ");
try {
new MySend();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
});
// 刷新聊天记录
MyFrame.btnRecord.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
});
}
}
class MyFrame {
Frame frame;
static Button btnSend, btnRecord, btnCancel, btnPost;
static TextArea inputField, recordField, receField;
static TextField ipField;
MyFrame() {
frame = new Frame("IP聊天");
frame.setSize(432, 500);
frame.setLayout(null);
frame.setLocation(400, 150);
frame.setResizable(false);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
frame.setBackground(Color.gray);
InputFrame();
}
public void InputFrame() {
Label label1 = new Label();
Label label2 = new Label("输入IP并提交:");
label1.setBounds(5, 10, 460, 200);
label2.setBounds(8, 465, 80, 30);
ipField = new TextField();
ipField.setBounds(85, 467, 148, 25);
inputField = new TextArea("", 5, 10, TextArea.SCROLLBARS_VERTICAL_ONLY);
recordField = new TextArea("", 5, 10, TextArea.SCROLLBARS_NONE);
receField = new TextArea("", 5, 10, TextArea.SCROLLBARS_VERTICAL_ONLY);
inputField.setBounds(5, 320, 420, 140);
inputField.setBackground(Color.cyan);
recordField.setBounds(430, 30, 165, 430);
recordField.setBackground(Color.cyan);
receField.setBounds(5, 30, 420, 285);
receField.setBackground(Color.cyan);
inputField.setFocusable(true);
receField.setFocusable(false);
recordField.setFocusable(false);
ipField.setFont(new Font("Monospaced", Font.BOLD, 15));
inputField.setFont(new Font("Monospaced", Font.BOLD, 25));
receField.setFont(new Font("Monospaced", Font.BOLD, 18));
recordField.setFont(new Font("Monospaced", Font.BOLD, 15));
btnCancel = new Button("取消");
btnSend = new Button("发送");
btnRecord = new Button("刷新纪录");
btnPost = new Button("提交");
btnCancel.setBounds(295, 465, 60, 30);
btnSend.setBounds(360, 465, 60, 30);
btnRecord.setBounds(435, 465, 80, 30);
btnPost.setBounds(240, 465, 50, 30);
frame.add(inputField);
// frame.add(recordField);
frame.add(receField);
frame.add(btnCancel);
frame.add(btnSend);
// frame.add(btnRecord);
frame.add(btnPost);
frame.add(label1);
frame.add(label2);
frame.add(ipField);
}
}