1. 程式人生 > >Java系列講座二:Socket網絡通信實現聊天軟件項目講解(UDP)

Java系列講座二:Socket網絡通信實現聊天軟件項目講解(UDP)

tcp 網絡通信 udp socket

上一篇我們講了通過TCP方式實現網絡通信軟件開發的原理,思路及實現,今天跟大家談談Socket通信中UDP方式通信的軟件開發步驟及主要代碼講解,UDP實現方式實現的通信軟件特點是不分客戶端與服務器端,一個程序既是客戶端與是服務器端,典型軟件是一些局域網的聊天軟件,如飛鴿等軟件。

UDP方式通信主要用到了java.net包中的3個類分別是DatagramPacket類,DatagramSocket類與InetAddress類,下面通過實現一個簡易聊天軟件小項目來講解他們的使用方法,代碼如下:

package T16;


import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.FlowLayout;

import java.awt.GridLayout;

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.util.Date;


import javax.swing.BorderFactory;

import javax.swing.JButton;

import javax.swing.JEditorPane;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTextField;

/**

* UDP通信的聊天軟件

*

* */

public class UDPChat extends JFrame implements ActionListener{


private JLabel lblPort,lblAddr,lblPort2;

private JTextField txtPort,txtAddr,txtPort2;

private JButton btnConn,btnSend,btnClose;

private JEditorPane txtReceive,txtSend;

public UDPChat(int n){

}

private UDPChat(int n,int m){

}

public UDPChat() {

super("UDP通信的聊天軟件");

lblPort = new JLabel("本機端口:",JLabel.RIGHT);

lblPort2 = new JLabel("對方端口:",JLabel.RIGHT);

lblAddr = new JLabel("對方地址:",JLabel.RIGHT);

txtPort = new JTextField("8888",5);

txtPort2 = new JTextField("9999",5);

InetAddress ipaddr =null;

try {

ipaddr = InetAddress.getLocalHost();

} catch (UnknownHostException e) {

e.printStackTrace();

}

txtAddr = new JTextField(ipaddr.getHostAddress(),10);

btnConn = new JButton("連接(C))");

btnConn.setMnemonic(‘C‘);

JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

topPanel.add(lblPort);

topPanel.add(txtPort);

topPanel.add(lblAddr);

topPanel.add(txtAddr);

topPanel.add(lblPort2);

topPanel.add(txtPort2);

topPanel.add(btnConn);

txtReceive = new JEditorPane();

txtSend = new JEditorPane();

JPanel centerPanel = new JPanel(new GridLayout(2,1,5,10));

centerPanel.add(txtReceive);

txtReceive.setBorder(BorderFactory.createLoweredBevelBorder());

//接收框不能編輯

txtReceive.setEditable(false);

txtSend.setBorder(BorderFactory.createLoweredBevelBorder());

centerPanel.add(txtSend);

btnSend = new JButton("發送(S)");

btnSend.setMnemonic(‘S‘);

btnClose = new JButton("退出(X)");

btnClose.setMnemonic(‘X‘);

JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

bottomPanel.add(btnSend);

bottomPanel.add(btnClose);

add(topPanel,BorderLayout.NORTH);

// centerPanel.setBackground(Color.RED);

add(centerPanel,BorderLayout.CENTER);

add(bottomPanel,BorderLayout.SOUTH);

btnConn.addActionListener(this);

btnSend.addActionListener(this);

btnClose.addActionListener(this);

//發送按鈕禁用

btnSend.setEnabled(false);

setSize(600, 400);

setVisible(true);

setLocationRelativeTo(null);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}


//創建內部類,實現接收線程

class ReceiveThread extends Thread{

DatagramSocket socket;

public ReceiveThread() {

try{

int port = Integer.parseInt(txtPort.getText().trim());

socket = new DatagramSocket(port);

}catch(Exception e){

e.printStackTrace();

}

}

@Override

public void run() {

byte[] b = new byte[1024];

DatagramPacket packet = new DatagramPacket(b,b.length);

while(true){

try {

//接收數據

socket.receive(packet);

//轉換為字符串

String str = new String(b,0,packet.getLength());

//顯示在接收框

String content = txtReceive.getText();

content += new Date().toLocaleString()+"\n";

content += str+"\n";

txtReceive.setText(content);

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

public static void main(String[] args) {

// UDPChat chat = new UDPChat();

try {

Class.forName("T16.UDPChat").newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}


@Override

public void actionPerformed(ActionEvent e) {

if(e.getSource()==btnConn){

btnConn.setEnabled(false);

btnSend.setEnabled(true);

//啟動線程

new ReceiveThread().start();

}else if(e.getSource()==btnSend){

//發送內容

String str = txtSend.getText().trim();

if(str.equals("")){

JOptionPane.showMessageDialog(this, "請輸入要發送的內容");

return;

}

//把要發送的內容顯示到接收框

String content = txtReceive.getText();

content += new Date().toLocaleString()+"\n";

content += str+"\n";

txtReceive.setText(content);

try {

//設置對方IP地址

InetAddress ip = InetAddress.getByName(txtAddr.getText().trim());

//設置對方的端口

int port = Integer.parseInt(txtPort2.getText().trim());

//創建發送包

byte b[] = str.getBytes();

DatagramPacket p = new DatagramPacket(b,b.length,ip,port);

//創建DatagramSocket發送

DatagramSocket socket = new DatagramSocket();

//發送

socket.send(p);

//清空發送框的內容

txtSend.setText("");

} catch (UnknownHostException e1) {

e1.printStackTrace();

} catch (SocketException e2) {

e2.printStackTrace();

} catch (IOException e3) {

e3.printStackTrace();

}

}else if(e.getSource()==btnClose){

System.exit(0);

}

}

}


該程序必須同啟動2個實例才能實現在局域網聊天,互相設置對方的端口與IP地址即可。

本人從事軟件項目開發20年,10年的Java工程師系列課程的教學工作,錄制30多門精品視頻課程,每門課程都包含有項目實戰,上課PPT,及完整的源代碼下載,有興趣的朋友可以看看我的在線課堂,

關於網絡即時通訊,多線程等技術的詳細介紹內容很多,如果大家有興趣可以看看我的 java從入門到精通+QQ即時通訊軟件項目實訓的教學視頻,鏈接地址:http://edu.51cto.com/course/6946.html

Java系列講座二:Socket網絡通信實現聊天軟件項目講解(UDP)