java 实现即时聊天设计(利用ip进行远程通信)

先看下效果图,一端运行在远程服务器,一端在本机电脑上运行,在局域网内两端可正常通信,由于我学校网络是局域网,所以外网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);

	}

}


你可能感兴趣的:(想到的小东西)