java中UDP簡(jiǎn)單聊天程序?qū)嵗a
學(xué)過(guò)計(jì)算機(jī)網(wǎng)絡(luò)通信的都知道,計(jì)算機(jī)之間傳送數(shù)據(jù)由兩種,即TCP通信和UDP通信。TCP是可靠的面向連接的通信協(xié)議,二UDP是不可靠的面向無(wú)連接的通信協(xié)議。
java中有基于TCP的網(wǎng)絡(luò)套接字通信,也有基于UDP的用戶數(shù)據(jù)報(bào)通信,UDP的信息傳輸速度快,但不可靠!
基于UDP通信的基本模式:
(1)將數(shù)據(jù)打包,稱為數(shù)據(jù)包(好比將信件裝入信封一樣),然后將數(shù)據(jù)包發(fā)往目的地。
(2)接受別人發(fā)來(lái)的數(shù)據(jù)包(好比接收信封一樣),然后查看數(shù)據(jù)包中的內(nèi)容。
客戶機(jī)
package com.client.view;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ObjectOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import com.tools.ClientToServerThread;
/**
* @author lenovo
*
*/
public class JChatFrm extends JFrame implements ActionListener{
JTextArea jta;
JTextField jtf;
JButton jb;
JPanel jp;
String ownerId;
String friendId;
ClientToServerThread ctsT;
public static void main(String[] args) {
// TODO Auto-generated method stub
new JChatFrm();
}
public JChatFrm()
{
setTitle("客戶端");
jta=new JTextArea();
jtf=new JTextField(15);
jb=new JButton("發(fā)送");
jb.addActionListener(this);
jp=new JPanel();
jp.add(jtf);
jp.add(jb);
this.add(jta,"Center");
this.add(jp,"South");
// this.setTitle(ownerId+" 正在和 "+friend+" 聊天");
this.setIconImage((new ImageIcon("image/qq.gif").getImage()));
// this.setSize(300, 200);
this.setBounds(300, 200, 300, 200);
this.setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ctsT = new ClientToServerThread(jta);
ctsT.start();
/**窗體關(guān)閉按鈕事件*/
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
if(JOptionPane.showConfirmDialog(null, "<html><font size=3>確定退出嗎?</html>","系統(tǒng)提示",JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE)==0)
{
System.exit(0);
ctsT.closeSocket();
}
else
{
return;
}
}
}
);
}
//寫一個(gè)方法,讓它顯示消息
public void showMessage(String message)
{
String info= message;
this.jta.append(info);
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getSource()==jb)
{
byte buffer[] = jtf.getText().trim().getBytes();
ctsT.sendData(buffer);
}
}
}
package com.tools;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Properties;
import javax.swing.JTextArea;
import com.common.User;
/**
* @author lenovo
*
*/
public class ClientToServerThread extends Thread{
private String serverIP = "127.0.0.1";
private int serverPORT = 8888;
private int receivePORT = 6666;
//聲明發(fā)送信息的數(shù)據(jù)報(bào)套結(jié)字
private DatagramSocket sendSocket = null;
//聲明發(fā)送信息的數(shù)據(jù)包
private DatagramPacket sendPacket = null;
//聲明接受信息的數(shù)據(jù)報(bào)套結(jié)字
private DatagramSocket receiveSocket = null;
//聲明接受信息的數(shù)據(jù)報(bào)
private DatagramPacket receivePacket = null;
//收發(fā)數(shù)據(jù)的端口
private int myPort = 0;
//接收數(shù)據(jù)主機(jī)的IP地址
private String friendIP = null;
private int friendPort = 0;
//緩沖數(shù)組的大小
public static final int BUFFER_SIZE = 5120;
private byte inBuf[] = null; //接收數(shù)據(jù)的緩沖數(shù)組
private byte outBuf[] = null; //發(fā)送數(shù)據(jù)的緩沖數(shù)組
JTextArea jta;
// 構(gòu)造函數(shù)
public ClientToServerThread(JTextArea jta) {
this.jta = jta;
getPropertiesInfo();
}
public void run() {
String receiveInfo = "";
try{
inBuf = new byte[BUFFER_SIZE];
receivePacket = new DatagramPacket(inBuf,inBuf.length);
receiveSocket = new DatagramSocket(receivePORT);
}catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
while (true) {
if(receiveSocket == null){
break;
} else {
try {
receiveSocket.receive(receivePacket);
String message = new String(receivePacket.getData(),0,receivePacket.getLength());
jta.append("收到數(shù)據(jù)"+message+"\n");
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}
}
/**
* 該方法用來(lái)獲得服務(wù)器屬性文件中的IP、PORT
*/
private void getPropertiesInfo(){
Properties prop = new Properties();
InputStream inStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("ServerInfo.properties");
try{
//獲得相應(yīng)的鍵值對(duì)
prop.load(inStream);
}catch(IOException e){
e.printStackTrace();
}
//根據(jù)相應(yīng)的鍵獲得對(duì)應(yīng)的值
serverIP = prop.getProperty("serverip");
serverPORT = Integer.parseInt(prop.getProperty("serverudp.port"));
receivePORT = Integer.parseInt(prop.getProperty("receiveudp.port"));
}
public void sendData(byte buffer[]){
try{
InetAddress address = InetAddress.getByName(serverIP);
// outBuf = new byte[BUFFER_SIZE];
sendPacket = new DatagramPacket(buffer,buffer.length,address,serverPORT);
sendSocket = new DatagramSocket();
sendSocket.send(sendPacket);
}catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
public void closeSocket(){
receiveSocket.close();
}
}
服務(wù)器:
package com.server.view;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ObjectOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import com.tools.ClientToServerThread;
/**
* @author lenovo
*
*/
public class JChatFrm extends JFrame implements ActionListener{
JTextArea jta;
JTextField jtf;
JButton jb;
JPanel jp;
String ownerId;
String friendId;
ClientToServerThread ctsT;
public static void main(String[] args) {
// TODO Auto-generated method stub
new JChatFrm();
}
public JChatFrm()
{
setTitle("服務(wù)器");
jta=new JTextArea();
jtf=new JTextField(15);
jb=new JButton("發(fā)送");
jb.addActionListener(this);
jp=new JPanel();
jp.add(jtf);
jp.add(jb);
this.add(jta,"Center");
this.add(jp,"South");
// this.setTitle(ownerId+" 正在和 "+friend+" 聊天");
this.setIconImage((new ImageIcon("image/qq.gif").getImage()));
// this.setSize(300, 200);
this.setBounds(300, 200, 300, 200);
this.setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ctsT = new ClientToServerThread(jta);
ctsT.start();
/**窗體關(guān)閉按鈕事件*/
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
if(JOptionPane.showConfirmDialog(null, "<html><font size=3>確定退出嗎?</html>","系統(tǒng)提示",JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE)==0)
{
System.exit(0);
ctsT.closeSocket();
}
else
{
return;
}
}
}
);
}
//寫一個(gè)方法,讓它顯示消息
public void showMessage(String message)
{
String info= message;
this.jta.append(info);
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getSource()==jb)
{
byte buffer[] = jtf.getText().trim().getBytes();
ctsT.sendData(buffer);
}
}
}
package com.tools;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Properties;
import javax.swing.JTextArea;
import com.common.User;
/**
* @author lenovo
*
*/
public class ClientToServerThread extends Thread{
private String sendIP = "127.0.0.1";
private int sendPORT = 6666;
private int receivePORT = 8888;
//聲明發(fā)送信息的數(shù)據(jù)報(bào)套結(jié)字
private DatagramSocket sendSocket = null;
//聲明發(fā)送信息的數(shù)據(jù)包
private DatagramPacket sendPacket = null;
//聲明接受信息的數(shù)據(jù)報(bào)套結(jié)字
private DatagramSocket receiveSocket = null;
//聲明接受信息的數(shù)據(jù)報(bào)
private DatagramPacket receivePacket = null;
//收發(fā)數(shù)據(jù)的端口
private int myPort = 0;
//接收數(shù)據(jù)主機(jī)的IP地址
private String friendIP = null;
private int friendPort = 0;
//緩沖數(shù)組的大小
public static final int BUFFER_SIZE = 5120;
private byte inBuf[] = null; //接收數(shù)據(jù)的緩沖數(shù)組
private byte outBuf[] = null; //發(fā)送數(shù)據(jù)的緩沖數(shù)組
JTextArea jta;
// 構(gòu)造函數(shù)
public ClientToServerThread(JTextArea jta) {
this.jta = jta;
getPropertiesInfo();
}
public void run() {
String receiveInfo = "";
try{
inBuf = new byte[BUFFER_SIZE];
receivePacket = new DatagramPacket(inBuf,inBuf.length);
receiveSocket = new DatagramSocket(receivePORT);
}catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
while (true) {
if(receiveSocket == null){
break;
} else {
try {
receiveSocket.receive(receivePacket);
String message = new String(receivePacket.getData(),0,receivePacket.getLength());
jta.append("收到數(shù)據(jù)"+message+"\n");
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}
}
/**
* 該方法用來(lái)獲得服務(wù)器屬性文件中的IP、PORT
*/
private void getPropertiesInfo(){
Properties prop = new Properties();
InputStream inStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("ServerInfo.properties");
try{
//獲得相應(yīng)的鍵值對(duì)
prop.load(inStream);
}catch(IOException e){
e.printStackTrace();
}
//根據(jù)相應(yīng)的鍵獲得對(duì)應(yīng)的值
receivePORT = Integer.parseInt(prop.getProperty("serverudp.port"));
}
public void sendData(byte buffer[]){
try{
InetAddress address = InetAddress.getByName(sendIP);
// outBuf = new byte[BUFFER_SIZE];
sendPacket = new DatagramPacket(buffer,buffer.length,address,sendPORT);
sendSocket = new DatagramSocket();
sendSocket.send(sendPacket);
}catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
public void closeSocket(){
receiveSocket.close();
}
}
運(yùn)行截圖:

- 使用Java和WebSocket實(shí)現(xiàn)網(wǎng)頁(yè)聊天室實(shí)例代碼
- java socket實(shí)現(xiàn)聊天室 java實(shí)現(xiàn)多人聊天功能
- java聊天室的實(shí)現(xiàn)代碼
- java實(shí)現(xiàn)自動(dòng)回復(fù)聊天機(jī)器人
- 基于Java Socket實(shí)現(xiàn)一個(gè)簡(jiǎn)易在線聊天功能(一)
- Java基于socket實(shí)現(xiàn)簡(jiǎn)易聊天室實(shí)例
- java Socket實(shí)現(xiàn)網(wǎng)頁(yè)版在線聊天
- java實(shí)現(xiàn)一個(gè)簡(jiǎn)單TCPSocket聊天室功能分享
- 基于java編寫局域網(wǎng)多人聊天室
- javaGUI實(shí)現(xiàn)多人聊天功能
相關(guān)文章
使用Mybatis對(duì)數(shù)據(jù)庫(kù)進(jìn)行單表操作的實(shí)現(xiàn)示例
這篇文章主要介紹了使用Mybatis對(duì)數(shù)據(jù)庫(kù)進(jìn)行單表操作的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Java中使用輾轉(zhuǎn)相除法求最大公約數(shù)
這篇文章主要介紹了Java中使用輾轉(zhuǎn)相除法求最大公約數(shù),本文直接給出代碼實(shí)例,需要的朋友可以參考下2015-05-05
詳解jenkins自動(dòng)部署springboot應(yīng)用的方法
這篇文章主要介紹了詳解jenkins自動(dòng)部署springboot應(yīng)用的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
springboot中Controller內(nèi)文件上傳到本地及阿里云操作方法
這篇文章主要介紹了springboot中Controller內(nèi)文件上傳到本地及阿里云操作方法,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-12-12
java中fastjson生成和解析json數(shù)據(jù)(序列化和反序列化數(shù)據(jù))
本篇文章主要介紹了java中fastjson生成和解析json數(shù)據(jù)(序列化和反序列化數(shù)據(jù)),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02
Spring?Boot?Admin?監(jiān)控指標(biāo)接入Grafana可視化的實(shí)例詳解
Spring Boot Admin2 自帶有部分監(jiān)控圖表,如圖,有線程、內(nèi)存Heap和內(nèi)存Non Heap,這篇文章主要介紹了Spring?Boot?Admin?監(jiān)控指標(biāo)接入Grafana可視化,需要的朋友可以參考下2022-11-11

