java udp簡單聊天程序_Java基于UDP協議實現簡單的聊天室程序

最近比較閑,一直在抽空回顧一些java方面的技術應用。

今天沒什么事做,基于udp協議,寫了一個非常簡單的聊天室程序。

現在的工作,很少用到socket,也算是對java網絡編程方面的一個簡單回憶。

先看一下效果:

37171f2926487f4eff565c7024078eca.png

實現的效果可以說是非常非常簡單,但還是可以簡單的看到一個實現原理。

“聊天室001”的用戶,小紅和小綠相互聊了兩句,“聊天室002”的小黑無人理會,在一旁寂寞著。

看一下代碼實現:

1、首先是消息服務器的實現,功能很簡單:?將客戶端的信息(進入了哪一個聊天室等)進行登記;

?構造udp協議套接字對象,接受各個客戶端發送的消息;

?解析消息內容,將聊天信息推送回對應聊天室的各個客戶端;

package com.tsr.simplechat.receive_server;

import java.io.ioexception;

import java.net.datagrampacket;

import java.net.datagramsocket;

import java.net.socketexception;

import java.util.arraylist;

import java.util.hashmap;

import com.google.gson.gson;

import com.tsr.simplechat.bean.messageentity;

import com.tsr.simplechat.client.chatclient;

//聊天服務器

public class chatserver extends thread {

// 程序占用端口號

private static final int port = 10000;

// 消息接受套接字對象

private static datagramsocket server = null;

// 字典對象(key:聊天室id,value:該聊天室下的客戶端用戶集合);

private static hashmap> groups = new hashmap>();

// 構造器

public chatserver() {

try {

// 消息接受套接字對象的構造初始化

server = new datagramsocket(port);

} catch (socketexception e) {

e.printstacktrace();

}

}

// 注冊聊天室新登錄用戶

public static void logingroup(string groupid, chatclient client) {

// 通過聊天室id,獲取該聊天室的所有在線用戶

arraylist clients = groups.get(groupid);

if (clients == null) {

clients = new arraylist();

}

// 將此次進入聊天室的用戶登記

clients.add(client);

// 更新聊天室信息

groups.put(groupid, clients);

}

// 循環接收消息

@override

public void run() {

while (true) {

receivemessage();

}

}

private void receivemessage() {

// udp數據包

byte[] buf = new byte[1024];

datagrampacket packet = new datagrampacket(buf, buf.length);

while (true) {

try {

// 接受數據包

server.receive(packet);

} catch (ioexception e) {

// todo auto-generated catch block

e.printstacktrace();

}

// 解析數據包,獲取聊天信息

string content = new string(packet.getdata(), 0, packet.getlength());

// 通過第三方包解析json數據

gson gson = new gson();

messageentity me = gson.fromjson(content, messageentity.class);

// 解析消息內容,通過聊天室id,獲取該聊天室的所有在線用戶

arraylist clients = groups.get(me.getgroupid());

// 將接收到的消息推送回該聊天室的各個用戶

for (chatclient client : clients) {

client.pushbackmessage(me);

}

}

}

}

2、客戶端程序,依然很簡單:

?簡單的定義客戶端聊天室界面。

?構造消息發送套接字對象。

?獲取聊天信息框的內容,發送到服務器。

package com.tsr.simplechat.client;

import java.awt.button;

import java.awt.event;

import java.awt.frame;

import java.awt.textarea;

import java.awt.textfield;

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.net.unknownhostexception;

import com.tsr.simplechat.bean.messageentity;

import com.tsr.simplechat.receive_server.chatserver;

//客戶端程序

public class chatclient extends frame {

private static final long serialversionuid = 1l;

// 聊天室id

private string groupid;

// 客戶端用戶名

private string clientname;

// 客戶端消息發送服務套接字

private datagramsocket msg_send;

// 服務端口

private final int port = 10000;

// 服務器ip地址

private inetaddress ip;

// 客戶端控件

textfield tf = new textfield(20);

textarea ta = new textarea();

button send = new button("send");

// 客戶端構造器

public chatclient(string groupid, string clientname) {

super("聊天室:" + groupid + "/" + clientname);

this.clientname = clientname;

this.groupid = groupid;

// 設置客戶端界面樣式

add("north", tf);

add("center", ta);

add("south", send);

setsize(250, 250);

show();

// 聊天相關服務器初始化

init();

// 監視器

addwindowlistener(new windowadapter() {

public void windowclosing(windowevent e) {

// 關閉消息發送服務

msg_send.close();

// 關閉客戶端程序

dispose();

system.exit(0);

}

});

}

// 聊天相關服務器初始化

private void init() {

// 注冊當前用戶及所在聊天室信息注冊到服務器

chatserver.logingroup(groupid, this);

try {

// 初始化消息發送套接字對象

msg_send = new datagramsocket();

// 指定消息服務器

try {

ip = inetaddress.getbyname("127.0.0.1");

} catch (unknownhostexception e) {

system.out.println("未知的主機異常..");

}

} catch (socketexception e) {

system.out.println("套接字連接異常..");

}

}

// 消息發送按鈕時間監聽

public boolean action(event evt, object arg) {

if (evt.target.equals(send)) {

try {

// 獲取輸入內容

string content = tf.gettext();

// 發送消息

send_message(content);

// 清空聊天框

tf.settext(null);

} catch (exception ioe) {

system.out.print(ioe.getmessage());

}

}

return true;

}

// 消息發送

private void send_message(string content) {

// 消息格式化(json格式)

string message = messageformat(content);

// 將消息封裝成udp數據包

byte[] buf = message.getbytes();

datagrampacket packet = new datagrampacket(buf, buf.length, ip, port);

try {

// 通過udp協議發送消息

msg_send.send(packet);

} catch (ioexception e) {

system.out.println("io異常..");

}

}

// 消息格式化

private string messageformat(string content) {

stringbuffer buffer = new stringbuffer();

buffer.append("{\"groupid\":").append("\"").append(groupid).append(

"\",");

buffer.append("\"username\":\"").append(clientname).append("\",");

buffer.append("\"text\":\"").append(content).append("\"}");

return buffer.tostring();

}

// 從服務器獲取當前聊天室最新消息(回調..)

public void pushbackmessage(messageentity me) {

ta.append(me.getusername() + ":" + me.gettext());

ta.append("\n");

}

}

3、消息實體類

主要就是用于將消息封裝成對象,包含:聊天室id、消息發送者昵稱,消息內容。使用json格式解析。

package com.tsr.simplechat.bean;

//消息實體

public class messageentity {

private string groupid;

private string username;

private string text;

public string getgroupid() {

return groupid;

}

public void setgroupid(string groupid) {

this.groupid = groupid;

}

public string getusername() {

return username;

}

public void setusername(string username) {

this.username = username;

}

public string gettext() {

return text;

}

public void settext(string text) {

this.text = text;

}

}

4、ok,到了這里就基本搞定了,建立一個測試類。

?開啟消息服務器。

?開啟三個客戶端,其中兩個進入“聊天室001”,另一個進入“聊天室002”。

import com.tsr.simplechat.client.chatclient;

import com.tsr.simplechat.receive_server.chatserver;

public class test {

public static void main(string[] args) {

chatserver r = new chatserver();

r.start();

chatclient c1 = new chatclient("001", "小紅");

chatclient c2 = new chatclient("001", "小綠");

chatclient c3 = new chatclient("002", "小黑");

}

}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持萬仟網。

希望與廣大網友互動??

點此進行留言吧!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530139.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530139.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java9 反應編程_Java9第四篇-Reactive Stream API響應式編程

file我計劃在后續的一段時間內,寫一系列關于java 9的文章,雖然java 9 不像Java 8或者Java 11那樣的核心java版本,但是還是有很多的特性值得關注。期待您能關注我,我將把java 9 寫成一系列的文章,大概十篇左右。Java 9的…

bb10系統支持java嗎_黑莓BB10怎么樣 BlackBerry 10系統好用嗎?

曾幾何時黑莓Blackberry OS是一款十分受用戶歡迎的手機系統,不過隨著手機系統市場已經被蘋果iOS、谷歌安卓、微軟Windows Phone三分天下,致使曾經的黑莓帝國逐漸淪陷,體驗和性能都已經明顯跟不上iOS與安卓等系統的腳步了,也因為如…

java中興參與實參相同_中興通訊_傳輸SDH試題(含答案)

中興傳輸SDH試題一、單項選擇題(每小題2分,共30分)1、在SDH系統中, RSOH指(A)。A.再生段開銷B.復用段開銷C.再生段通道開銷D.復用段通道開銷2.、同步數字體系SDH具有(A)幀結構。A.塊狀B.串行C.鏈形D.三維3、管理指針單元的作用是(A)。A、用來指示信息凈負荷的第一個…

php 正則提取url,php 正則表達式提取網頁超級鏈接url的函數

function match_links($document) {preg_match_all("]))[^>]*>?(.*?)isx",$document,$links);while(list($key,$val) each($links[2])) {if(!empty($val))$match[link][] $val;}while(list($key,$val) each($links[3])) {if(!empty($val))$match[link][] …

php array colum,php5.5新數組函數array_column使用

array_column 用于獲取二維數組中的元素(PHP 5 > 5.5.0),但我們有時候需要在低版本中使用,那么就可以使用下面的代碼即可PHP5.5發布了,其中增加了一個新的數組函數array_column,感覺不錯的!但是低版本PHP要使用&…

php 將字符串打亂,PHP內部實現打亂字符串順序函數str_shuffle的方法

前言2019年春節已過,今天是上班第一天,還得翻一翻之前沒有看完的PHP源碼。今天聊的是字符串順序打亂函數str_shuffle。這個函數本身使用頻率并不高。但是,其內部實現還是非常有趣的。str_shuffle() 函數隨機地打亂字符串中的所有字符。要注意…

php+js+return+true,js中return、return false、return true的區別

1.語法及返回方式①返回控制與函數結果語法為:return 表達式;語句結果函數的執行,返回調用函數,而且把表達式的值作為函數結果返回出去②返回控制無函數結果語法為:return;在大多數情況下,為事件處理函數如果讓其返回false,可以防止默認的事件行為.例如,默認情況下,點擊一個標簽…

php strlen遇0截斷,聊下php下的截斷問題

0x01 起因有天在群里說起上傳的%00截斷的一些問題,就想起之前自己在這個問題踩過坑,想起了自己曾經的flag說要寫文章,一直沒寫,現在來填坑了。0x02 經過源碼理解1234//test.phpinclude "1.txt\000.jpg";?>1234//1.t…

test.php.bak,記一次phpmyadmin 4.8.1 遠程文件包含漏洞(BUUCTF web)

題目很簡單,一個滑稽打開源碼,發現存在source.php文件于是訪問文件,發現出現一串php源碼提示存在hint.php,于是訪問發現一句話flag not here, and flag in ffffllllaaaagggg再回過頭來觀察source.php明顯是一道代碼審計的問題&…

php中files和FILRS,php獲取文件內容最后一行示例

php獲取文件內容最后一行示例復制代碼 代碼如下:$rs README.md;$fp fopen($rs, r);fseek($fp,-1,SEEK_END);$s ;while(($c fgetc($fp)) ! false){if($c "\n" && $s) break;$s $c . $s;fseek($fp, -2, SEEK_CUR);}fclose($fp);echo $s;exit;時間&#x…

php 實現貪吃蛇游戲,C++實現簡單貪吃蛇游戲

我大概在一個多月前把自己上學期寫的c代碼的貪吃蛇游戲push到csdn上,并且說c風格的貪吃蛇寫起來有些麻煩(貪吃蛇游戲的c語言實現),準備用面向對象的c再寫一遍。現在我們專業恰好剛教完了c,學校也布置了一道簡單的貪吃蛇的編程題目&#xff0c…

java中的斜杠和反斜杠,老生常談java路徑中的反斜杠和斜杠的區別

JAVA中的斜杠有正斜杠與反斜杠之分,正斜杠,一般就叫做斜杠,符號為“/”;反斜杠的符號為“\”。斜杠(/)在JAVA中沒有什么特別的意義,就是代表一個字符‘/;反斜杠(\)則不然,它和緊跟著它的那個字符構成轉義字…

小程序 php cookie,微信小程序使用Cookie

微信小程序使用Cookie微信小程序不支持Cookie,因此,需要借助小程序的數據緩存來實現Cookie.環境: mpvue fly.js登錄成功后,在處理登錄驗證的method里,加入以下內容保存Cookie:wx.setStorageSync("sessionid",response.headers["set-cookie"][0])我對fly.j…

php對象好用嗎,在數據庫中使用對象的好處_php

我們都知道如何從mysql獲取我們需要的行(記錄),讀取數據,然后存取一些改動。很明顯也很直接,在這個過程背后也沒有什么拐彎抹角的。然而對于我們使用面對對象的程序設計(OOP)來管理我們數據庫中的數據時,這個過程就需要大大改進一…

linux apache php顯示源碼,linux 源碼安裝apache PHP 問題

sudo ./configure --prefix/var/php --with-apxs2/usr/local/apache2/bin/apxsLoadModule php5_module modules/libphp5.soDirectoryIndex index.html index.html.var .phpa-bash-3.2$ pwd/usr/local/apache2/htdocs-bash-3.2$ cat info.phpphpinfo();?>打開info.ph…

mysql臨時表的的理解,如何理解存儲過程中已存在的mysql臨時表?

它在創建表時具有IF NOT EXISTS(13.1.17. CREATE TABLE Syntax)選項,在這種情況下可以使用.例:DELIMITER $$CREATE PROCEDURE temp_sp1()BEGINCREATE TEMPORARY TABLE IF NOT EXISTS temp_table (col2 int(11) DEFAULT NULL,col3 int(11) DEFAULT NULL);INSERT INTO…

python 發郵件 抄送,Python調用outlook發送郵件,發送給多人、抄送給多人并帶上附件...

我的報告目錄具體解釋在代碼中有詳細注釋import win32com.client as win32import datetime, osaddressee test01qq.com;test02jd.com#收件人郵箱列表cc test02163.com;test03alibaba.com#抄送人郵件列表mail_path os.path.join(rC:\Users\songlihui\PycharmProjects\test001…

php阻止輸入sql,在PHP中全面阻止SQL注入式攻擊之三

一、 建立一個安全抽象層我們并不建議你手工地把前面介紹的技術應用于每一個用戶輸入的實例中,而是強烈推薦你為此創建一個抽象層。一個簡單的抽象是把你的校驗方案加入到一個函數中,并且針對用戶輸入的每一項調用這個函數。當然,我們還可以創…

Oracle12081,【Oracle介質】Oracle 12C Linux x86-64 最新OPatch patch 6880880 12.2.0.1.7

天萃荷凈Linux x86-64 補丁程序6880880: OPatch patch of version 12.2.0.1.7 for Oracle software releases 12.1.0.x (installer) and 12.2.0.x (AUG 2016)上次更新時間 2016-8-26 上午1:48 (8 天前)產品 Oracle Global Lifecycle Management OPatc…

如何使用oracle ebs,Oracle EBS進行集成的實際操作步驟

我們今天主要向大家介紹的是如何使用WebService和Oracle EBS進行集成,以及在使用WebService和Oracle EBS進行集成時,所需要的一些項目的描述,以下的文章就是對相關內容的描述。架構系統從總體上分為兩部分,一部為企業的EBS及接口系…