*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}

.hljs-comment,
.hljs-template_comment,
.diff .hljs-header,
.hljs-javadoc {
color: #998;
font-style: italic;
}

.hljs-keyword,
.css .rule .hljs-keyword,
.hljs-winutils,
.javascript .hljs-title,
.nginx .hljs-title,
.hljs-subst,
.hljs-request,
.hljs-status {
color: #333;
font-weight: bold;
}

.hljs-number,
.hljs-hexcolor,
.ruby .hljs-constant {
color: #099;
}

.hljs-string,
.hljs-tag .hljs-value,
.hljs-phpdoc,
.tex .hljs-formula {
color: #d14;
}

.hljs-title,
.hljs-id,
.coffeescript .hljs-params,
.scss .hljs-preprocessor {
color: #900;
font-weight: bold;
}

.javascript .hljs-title,
.lisp .hljs-title,
.clojure .hljs-title,
.hljs-subst {
font-weight: normal;
}

.hljs-class .hljs-title,
.haskell .hljs-type,
.vhdl .hljs-literal,
.tex .hljs-command {
color: #458;
font-weight: bold;
}

.hljs-tag,
.hljs-tag .hljs-title,
.hljs-rules .hljs-property,
.django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal;
}

.hljs-attribute,
.hljs-variable,
.lisp .hljs-body {
color: #008080;
}

.hljs-regexp {
color: #009926;
}

.hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.lisp .hljs-keyword,
.tex .hljs-special,
.hljs-prompt {
color: #990073;
}

.hljs-built_in,
.lisp .hljs-title,
.clojure .hljs-built_in {
color: #0086b3;
}

.hljs-preprocessor,
.hljs-pragma,
.hljs-pi,
.hljs-doctype,
.hljs-shebang,
.hljs-cdata {
color: #999;
font-weight: bold;
}

.hljs-deletion {
background: #fdd;
}

.hljs-addition {
background: #dfd;
}

.diff .hljs-change {
background: #0086b3;
}

.hljs-chunk {
color: #aaa;
}

#container {
padding: 15px;
}
pre {
border: 1px solid #ccc;
border-radius: 4px;
display: block;
background-color: #f8f8f8;
}
pre code {
white-space: pre-wrap;
}
.hljs,
code {
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
}
:not(pre) > code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
white-space: nowrap;
border-radius: 4px;
}
-->

UDP通信需要明确的几点:

  1. UDP通信不是面向连接的,发送端不管接收端是否启动是否能接收,发完数据报就结束。
  2. 无论是发送端还是接收端,都需要描述两个对象:套接字和数据报。
  3. 接收端的套接字对象中必须明确接收端口,且必须和发送端指定的目标端口一致。而发送端的套接字中则一般采用随机分配的发送端口。
  4. 无论是发送端还是接收端,数据报中都记录了自己和对方的socket信息(ip+port),还提供了用于发送或接收的数据缓冲区。这些数据只有数据报对象自己最清楚,如getPort(),getAddress(),getData()等。
    • (1).只不过对于发送端来说,创建发送报文对象需要指定目标套接字信息(ip+port),还需明确数据发送缓冲区。
    • (2).而对于接收端来说,则只需明确一个数据接收缓冲区即可。
  5. 接收端应该不断循环地负责接收。
  6. UDP套接字类DatagramSocket,UDP数据报类DatagramPacket。

UDPSender端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException; public class UDPSender { public static void main(String[] args) {
DatagramSocket dgs = null;
try {
// 1. 创建udp发送端的socket,一般使用随机发送端口
dgs = new DatagramSocket(); // 2. 创建udp报文包对象
// 2.1 创建数据发送缓冲区
String text = "Hello World! I'm coming";
byte[] buf = text.getBytes(); // 2.2 创建发送数据报文对象
InetSocketAddress isa = new InetSocketAddress("192.168.0.124",8888);
DatagramPacket dgp = new DatagramPacket(buf,buf.length,isa);
//DatagramPacket dgp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.0.124"), 8888); // 3.发送udp报文
dgs.send(dgp); } catch (SocketException e1) {
e1.printStackTrace();
} catch (UnknownHostException e2) {
e2.printStackTrace();
} catch (IOException e3) {
e3.printStackTrace();
} finally {
// 4. 关闭套接字
dgs.close();
}
}
}

UDPRecver端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; public class UDPRecver { public static void main(String[] args) {
while(true){
// 1.创建udp接收套接字,接收端必须指定正确的端口
DatagramSocket dgs = null;
try {
dgs = new DatagramSocket(8888); // 2. 创建udp接收数据包对象
byte[] buf = new byte[1024];
DatagramPacket dgp = new DatagramPacket(buf, buf.length); // 3.从套接字中接收数据到数据包中
dgs.receive(dgp); // 4.展示udp发送端相关信息,包括发送的数据
String data = new String(dgp.getData(), 0, dgp.getLength());
String ip = dgp.getAddress().getHostAddress();
int port = dgp.getPort();
System.out.println("Data: "+data+" ip: "+ip+" port: "+port);
} catch (SocketException s) {
s.printStackTrace();
} catch (IOException i) {
i.printStackTrace();
} finally {
dgs.close();
}
}
}
}

UDP实现群聊:

思路:

  1. 一个线程负责发,一个线程负责收,因此使用多线程。
  2. 发送端的数据报目标端应该指定为广播目标。且发送的数据来源于键盘输入。
  3. 接收端要无限循环接收数据,但应该提供下线离开功能。(假设收到了"bye",就表示下线)
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException; public class QunChat {
public static void main(String[] args) throws SocketException {
//发送端和接收端套接字,接收端套接字端口为8888,需要传递给发送端的报文对象
DatagramSocket send_socket = new DatagramSocket();
DatagramSocket recv_socket = new DatagramSocket(8888); Sender sender = new Sender(send_socket,8888);
Recver recver = new Recver(recv_socket); Thread send_thread1 = new Thread(sender);
Thread recv_thread1 = new Thread(recver);
send_thread1.start();
recv_thread1.start();
}
} class Sender implements Runnable {
private DatagramSocket send_sock;
private int dest_port;
Sender(DatagramSocket s,int port){ //初始化时就指定目标端口
this.send_sock = s;
this.dest_port = port;
} public void run() {
while(true) {
try {
//群聊发送目标,以广播为例
InetSocketAddress isa = new InetSocketAddress("192.168.0.255", dest_port);
//从键盘接收数据
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line=bufr.readLine())!=null) {
//如果发送的是bye,则断开,且不发送给接收端
if(line.equals("bye")) break; byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length, isa);
send_sock.send(dp);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
send_sock.close();
}
}
}
} class Recver implements Runnable {
private DatagramSocket recv_sock;
Recver(DatagramSocket socket){
this.recv_sock = socket;
} public void run() {
while(true) {
try {
//接收报文对象
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
recv_sock.receive(dp);
String src_ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
if(data.equals("bye")) System.out.println(src_ip +" leaving");;
System.out.println("Recviving data: "+ data+" from "+src_ip );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!

java 网络编程之UDP通信和简单的群聊程序的更多相关文章

  1. java 网络编程之TCP通信和简单的文件上传功能

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  2. Java网络编程之UDP

    Java网络编程之UDP 一.C/S架构中UDP网络通信流程 ①创建DatagramSocket与DatagramPacket对象 ②建立发送端,接收端 ③建立数据包 ④调用Socket的发送.接收方 ...

  3. java网络编程之UDP通讯

    详细介绍了java中的网络通信机制,尤其是UDP协议,通过对UDP的基本使用进行举例说明如何使用UDP进行数据的发送接收,并举了两个小demo说明UDP的使用注意事项. UDP协议原理图解: UDP协 ...

  4. Java网络编程之TCP通信

    一.概述 Socket类是Java执行客户端TCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信.Socket类的方法会建立和销毁连接,设置各种Socket选项. Server ...

  5. java网络编程之UDP实例

    package Socket; import java.net.DatagramPacket; import java.net.InetAddress; public class Dgram { pu ...

  6. Java网络编程之TCP、UDP

    Java网络编程之TCP.UDP 2014-11-25 15:23 513人阅读 评论(0) 收藏 举报 分类: java基础及多线程(28) 版权声明:本文为博主原创文章,未经博主允许不得转载.   ...

  7. 网络编程之UDP编程

    网络编程之UDP编程 UDP协议是一种不可靠的网络协议,它在通信的2端各建立一个Socket,但是这个Socket之间并没有虚拟链路,这2个Socket只是发送和接受数据的对象,Java提供了Data ...

  8. Java网络编程之URLConnection

    Java网络编程之URLConnecton 一.URLConnection简介 URLConnection是一个抽象类,表示指向URL指定资源的活动连接.URLConnection有两个不同但相关的用 ...

  9. Java网络编程之InetAddress浅析

    Java网络编程之InetAddress浅析 一.InetAddress综述 IP地址是IP使用的32位(IPv4)或者128位(IPv6)位无符号数字,它是传输层协议TCP,UDP的基础.InetA ...

随机推荐

  1. [转载]常见slave 延迟原因以及解决方法

    一  序言在运维线上M-M 架构的MySQL数据库时,接收的比较多关于主备延时的报警: 点击(此处)折叠或打开 check_ins_slave_lag (err_cnt:1)critical-slav ...

  2. jetty和tomcat的区别

    jetty:是一个开源的servlet容器,基于java的web容器,例如给jsp和servlet提供运行环境,jetty是使用java编写的,他的api是一组以jar包的形式发布,开发人员可以将je ...

  3. python将数据写入excel代码,python与office交互

    # -*- coding: utf-8 -*- from smartframe.header import * import pymysql import json import importlib, ...

  4. HTML5——localStorage

    html5的学习,忘记的差不多了,特地拿出来重新记录一下,从它的本地存储开始吧! 假设这样的html结构: <div id= "one_storage" class=&quo ...

  5. Spring Boot快速入门(一): Hello Spring Boot

    原文地址:https://lierabbit.cn/articles/2 一.准备工作 java环境:jdk 1.8 开发工具:idea 二.创建项目 打开idea 点击Create New Proj ...

  6. 同时安装python2和python3

    Windows 10 上已经安装了Anaconda2 和 python2.7 [工作需要] 想安装Anaconda3 和 python3 [学习需要] 以 Anaconda2 为主,3为辅. 要点: ...

  7. Python3.5下安装&测试Scrapy

    1.引言 Scrapy框架结构清晰,基于twisted的异步架构可以充分利用计算机资源,是做爬虫必备基础,本文将对Scrapy的安装作介绍. 2.安装lxml 2.1  下载地址:https://ww ...

  8. 【转载】wifi一键配网smartconfig原理及应用

    物联网给我们又提供了一种窃取WiFi密码的好方式:让智能设备主动断线. 同时也提供一种让智能设备连接到恶意WiFi的方式:设备一键配置功能时疯狂广播恶意WiFi的信息. 转自:http://blog. ...

  9. ESLint 使用入门 - 来自推酷

    在团队协作中,为避免低级 Bug.产出风格统一的代码,会预先制定编码规范.使用 Lint 工具和代码风格检测工具,则可以辅助编码规范执行,有效控制代码质量. 在以前的项目中,我们选择 JSHint 和 ...

  10. --------驱动开发之 ObReferenceObjectByName() 故障排查--------

    ------------------------------------------------------ 在写 filter driver 或 rootkit 时,经常需要 attach 到设备栈 ...