前段时间学到Socket套接字,对tcp/ip通信很感兴趣,便想编写测试下,很是简单。写到博客上分享下,最重要的是有一些不明白的问题希望有人给予解答。本实例采用DatagramSocket、DatagramPacket通信,指定目标IP地址即可发送信息,可向局域网外的公网IP主机发信息,如何接受来自公网IP的信息?如何穿透路由器到达指定内网IP主机?
设计思路:需要GUI组件简单设计个页面;局域网通信,用tcp通信,client对client,所以只编写一个client就好了;client之间通信用DatagramSocket、DatagramPacket收发数据包,同时用多线程分别封装发送数据包,接收数据包;最后解析数据包,用IO流解析得到的信息,显示在文本区。
页面:
过于简单直接发代码:
import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;import java.net.UnknownHostException;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;
import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.*;
public class chat{private JLabel ipjl;private JLabel portjl;private JTextField ipjtf;private JTextField portjtf;private JScrollPane messagejs;private JScrollPane sendjs;private JTextArea messagejta;private JTextArea sendjta;private JButton sendjb;private DatagramSocket dgssend;private DatagramSocket dgsrece;private DatagramPacket dgp;private String message;private String readmessage;private InetAddress ip;private int port;public chat() throws IOException{dgssend = new DatagramSocket();dgsrece = new DatagramSocket(8888);dgp = null;message = null;creatFrame();readmessages sm = new readmessages();Thread t = new Thread(sm);t.start();}public void creatFrame(){JFrame chatroom = new JFrame("聊天");chatroom.setLayout(new BorderLayout());chatroom.setBounds(650, 200, 800, 680);JPanel north = new JPanel();JPanel center = new JPanel();JPanel south = new JPanel();north.setPreferredSize(new Dimension(820,80));south.setPreferredSize(new Dimension(820,160));chatroom.add(north,BorderLayout.NORTH);chatroom.add(center);chatroom.add(south,BorderLayout.SOUTH);ipjl = new JLabel("对方IP地址");ipjtf = new JTextField("",15);portjl = new JLabel("对方端口");portjtf = new JTextField("8888",15);messagejta = new JTextArea("",20,70);messagejs = new JScrollPane(messagejta);messagejta.setEditable(false);sendjta = new JTextArea("",6,70);sendjs = new JScrollPane(sendjta);sendjb = new JButton("发送");sendjb.addActionListener(new sendmessage());north.add(ipjl);north.add(ipjtf);north.add(portjl);north.add(portjtf);center.add(messagejs);south.add(sendjs);south.add(sendjb);chatroom.setVisible(true);chatroom.setDefaultCloseOperation(chatroom.EXIT_ON_CLOSE);
}class sendmessage implements ActionListener {
@Overridepublic void actionPerformed(ActionEvent arg0) {try{message = sendjta.getText();ip = InetAddress.getByName(ipjtf.getText());port = Integer.parseInt(portjtf.getText());dgp = new DatagramPacket(message.getBytes(),message.getBytes().length,ip,port);Date date = new Date();DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");messagejta.append("我: " +format.format(date) + '\n');messagejta.append( message +" "+ '\n');// messagejta.setText(messagejta.getText()+"\r\n"+"我:"+message+"\r\n");dgssend.send(dgp);sendjta.setText("");}catch(Exception e){e.printStackTrace();}}
}
class readmessages implements Runnable{
@Overridepublic void run() {while(true){try{byte[] buf = new byte[1024];DatagramPacket dgpread = new DatagramPacket(buf,buf.length);dgsrece.receive(dgpread);String readmessage = new String(dgpread.getData(),0,dgpread.getLength());// ipjtf.setText(dgpread.getAddress().toString());// portjtf.setText(dgpread.getPort()+"");Date date = new Date();DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");messagejta.append(dgpread.getAddress().toString()+": " +format.format(date) + '\n');messagejta.append( readmessage + '\n');// messagejta.setText(messagejta.getText()+"\r\n"+dgpread.getAddress().toString()+":"+readmessage);}catch(Exception e){e.getStackTrace();}}}}
public static void main(String[] args) throws IOException{// TODO Auto-generated method stubnew chat();}
}