我以前经常写的是基于TCP的网络编程,由于TCP建立连接鼻血要经过三次握手连接,服务器端需要阻塞式等待客户端的连接。而UDP则是可以直接向目的地址的目的端口上发送数据包,由于它只负责发送出去就好,不管对方是否正确接受到与否,所以当网络性能不好时它容易出现丢包的问题。(注意:UDP是基于数据报为单位进行传输的,而TCP是一种基于流进行传输的)

  但是UDP很好的模拟了我们呢平时聊天的方式,可以很好的实现连续多次发送和接受,也就是简单的QQ聊天的功能。

  现在来简要介绍Java中有关UDP编程相关的类:

  一个是DatagramPacket,主要用来将数据字节填充到UDP数据报中,用来解包接受数据的,用来收和发UDP数据报。一个是DatagramSocket主要用来是建立客户端和服务器端,用来接受和发送数据报数据的。

  (1)DatagramPacket类

  UDP首部向IP首部添加了8个字节,包含了源端口和目标端口,IP首部以后内容的长度和校验和,最多有65507个字节数。UDP所使用的端口和TCP使用的端口不一样的,是一个final类。

  对于接受数据,将接受到的数据存储到DatagramPacket,然后从该对象中读取数据。

  对于发送数据,将发送的数据先存到DatagramPacket中,然后将该对象发送。

  接受数据报构造函数:
  DatagramPacket(byte[] buffer,int length)
  DatagramPacket(byte[] buffer,int offset,int length)
  socket将接受到的数据部分存储到buffer,一般buffer的大小最多定义为8192或者512大小即可
 
  发送数据报构造函数:
  由于DatagramPacket将数据填充到UDP数据报中,而数据报需要源端口和目标端口,客户端一般创建的端口是匿名的,会在填充的过程中自动的加上,而源端口必须要首先显式的在    DatagramPacket中设置,这样才能填充到UDP数据报中。发送数据都必须要把数据以字节形式发送。以API 1.6
  DatagramPacket(byte[] buffer,int length,InetAddress dest,int port)
  DatagramPacket(byte[] buffer,int offset,int length,InetAddress dest,int port)
  DatagramPacket(byte[] buffer,int length,SocketAddress dest)
  DatagramPacket(byte[] buffer,int offset,int length,SocketAddress dest)
   注意:SocketAddress是一个抽象类,主要保存了主机名、IP和端口号,
       一般可以SocketAddress address=new InetSocketAddress("www.baidu.com",2000)
       InetAddress只是用来保存主机名和IP的。
  InetAddress getAddress()、getPort()获取发送数据目标地址、端口和接受到数据的源地址、端口
  SocketAddress getSocketAddress()(最常用的)一样的意思。
 
  利用getData()获取接受到的数据报数据的字节数组,一般利用
  String res=new String(packet.getData(),"ASCII")或
  String s=new String(packet.getData(),packet.getOffset(),packet.getLength(),"UTF-8");
  获取数据。getLength()返回UDP中数据的字节数。getOffset()数据报中数据开始的点。
 
  

  对于已经构造好的DatagramPacket,可以在发送之前更改它的一些状态。修改数据报的属性,一般是先创建一个接受数据报的构造函数,然后对其报进行更改属性。
  setData(byte[] data)
  setData(byte[] data,int offset,int length) 可以用来连续发送大量的数据块
  setAddress(InetAddress remote)
  setPort(int port)
  setAddress(SocketAddress remote)相当于上面两个方法。可以利用这些方法来设置一个数据报发送不同的ip和端口。
  setLength(int length)设置包的长度,主要是指定缓冲区中将要发送的字节数,或用来将要接收数据的包数据缓冲区的字节数。
  
  (2)DatagramSocket类
  在UDP中没有明显的客户端类和服务器端类,客户端既可以发消息也可以接受消息。均在创建的过程会有SocketException异常。创建UDP客户端构造器

  DatagramSocket();创建一个对于客户端来说匿名的端口,发送UDP的过程会自动加上该端口号,服务器接受消息也会按照该端口号发送。
  创建UDP服务器构造器
  DatagramSocket(int port)
  DatagramSocket(int port,InetAddress interface);用于一个主机有多个网络接口的时候
  DatagramSocket(SocketAddress interface)
 
  发送数据报
  直接调用send(DatagramPacket dp),异常有IOException
  接受数据报
  receive(DatagramPacket dp);异常有IOException
  从网络中接受一个UDP数据报,存储在某一个DatagramPacket。在数据未到达之前会一直阻塞后面的运行,一般在无限循环中接受。
 
  管理连接
  connect(InetAddress host,int port)来设置其只对指定的远程主机和指定远程的接受和发送包
  getPort()、getInetAddress()返回其连接的远程主机。一般在接受到消息后,需要调用
  packet.getSocketAddress(),获取远程主机基本信息

  以下是我写的简单的一个聊天程序:

Send_Thread.java

package Chat_UDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Scanner; public class Send_Thread extends Thread{ //发送的socket端
private DatagramSocket sender = null;
//待发送的目标地址
private InetSocketAddress address = null;
//从键盘输入
Scanner scan = new Scanner(System.in); public Send_Thread(DatagramSocket sender,InetSocketAddress address)
{
this.sender = sender;
this.address = address;
} @Override
public void run() {
// TODO Auto-generated method stub
try
{
while(true)
{
//输入待发送的内容
String input = scan.nextLine();
if(input.equals("exit"))
break;
byte[] data = null;
data = input.getBytes("UTF-8");
//创建UDP数据报
DatagramPacket pack = new DatagramPacket(data, data.length,address); sender.send(pack);
} System.out.println("Exit!"); }catch(IOException e)
{
System.out.println("IOException");
}
} }

Receive_Thread.java

package Chat_UDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; public class Receive_Thread extends Thread { private static final int MAX_RECEIVE_BUFFER = 1024;
private DatagramSocket server;
private DatagramPacket packet;
byte[] buffer = new byte[MAX_RECEIVE_BUFFER]; public Receive_Thread(DatagramSocket server)
{
this.server = server;
packet = new DatagramPacket(buffer, buffer.length);
} @Override
public void run() {
// TODO Auto-generated method stub
try
{
while(true)
{
//接收数据包
server.receive(packet);
String s = new String(packet.getData(),packet.getOffset(),packet.getLength(),"UTF-8");
System.out.println(packet.getAddress()+" at port "+packet.getPort()+" Says :"+s);
packet.setLength(buffer.length);
}
}
catch(IOException e)
{
System.out.println("IOException");
}
}
}

Chat_Client.java

 package Chat_UDP;

 import java.net.DatagramSocket;
import java.net.InetSocketAddress; public class Chat_Client { private static final int DEST_PORT = 9000;
private static final int SEND_PORT = 10000;
private static final int RECE_PORT = 8888;
private static final String IP = "127.0.0.1"; public static void main(String[] args)
{
try{
Send_Thread send_thread = null;
Receive_Thread rece_thread = null;
InetSocketAddress address = null;
//创建待接受数据包的目的机的端口号和IP地址
address = new InetSocketAddress(IP, DEST_PORT);
//创建发送的Socket端
DatagramSocket sendsocket = new DatagramSocket(SEND_PORT);
//创建接受的Socket端
DatagramSocket recesocket = new DatagramSocket(RECE_PORT);
//发送线程建立
send_thread = new Send_Thread(sendsocket, address);
//接受线程的建立
rece_thread = new Receive_Thread(recesocket); send_thread.start();
rece_thread.start(); }catch(Exception e)
{
System.out.println("Exception!");
} } }

 Chat_Server.java

 package Chat_UDP;

 import java.net.DatagramSocket;
import java.net.InetSocketAddress; public class Chat_Server { private static final int DEST_PORT = 8888;
private static final int SEND_PORT = 10001;
private static final int RECE_PORT = 9000;
private static final String IP = "127.0.0.1"; public static void main(String[] args)
{
try{
Send_Thread send_thread = null;
Receive_Thread rece_thread = null;
InetSocketAddress address = null;
//创建待接受数据包的目的机的端口号和IP地址
address = new InetSocketAddress(IP, DEST_PORT);
//创建发送的Socket端
DatagramSocket sendsocket = new DatagramSocket(SEND_PORT);
//创建接受的Socket端
DatagramSocket recesocket = new DatagramSocket(RECE_PORT);
//发送线程建立
send_thread = new Send_Thread(sendsocket, address);
//接受线程的建立
rece_thread = new Receive_Thread(recesocket);
send_thread.start();
rece_thread.start();
}catch(Exception e)
{
System.out.println("Exception!");
} } }

Java UDP实现聊天功能代码的更多相关文章

  1. Java UDP实现聊天功能代码【转】

    感谢大佬大佬!!!:https://www.cnblogs.com/woshijpf/p/3735684.html 我以前经常写的是基于TCP的网络编程,由于TCP建立连接鼻血要经过三次握手连接,服务 ...

  2. 用UDP实现聊天功能

    // SK003Dlg.cpp : implementation file //   #include "stdafx.h" #include "SK003.h" ...

  3. Android 聊天功能

    记录一个聊天功能代码,以后有时间再分析吧. GIt的地址:https://github.com/Maxi-Mao/ChatDemo 链接:https://pan.baidu.com/s/1NaXEkT ...

  4. Java 网络编程 --基于UDP实现一对一聊天功能

    UDP 基本流程: UDP发送端基本流程: 1.使用DatagramSocket 指定端口 创建发送端 2.准备数据 一定转成字节数组 3. 封装成DatagramPacket 包裹,需要指定目的地 ...

  5. java网络编程(4)——udp实现聊天

    UDP可以实现在线聊天功能,我这里就是简单模拟一下: 发送端: package com.seven.udp; import java.io.BufferedReader; import java.io ...

  6. 采用tcp协议和UDP协议实现简单的聊天功能

    Date: 2019-06-19 Author: Sun 一. Python3输出带颜色字体 实现过程: ​ 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. ​ 转义 ...

  7. JAVA结合WebSocket实现简单客服聊天功能

    说明:该示例只简单的实现了客服聊天功能. 1.聊天记录没有保存到数据库中,一旦服务重启,消息记录将会没有,如果需要保存到数据库中,可以扩展 2.页面样式用的网上模板,样式可以自己进行修改 3.只能由用 ...

  8. 编写Java程序,应用客户端和服务端通过 Eclipse 控制台的输入和显示实现简易的聊天功能

    查看本章节 查看作业目录 需求说明: 应用客户端和服务端通过 Eclipse 控制台的输入和显示实现简易的聊天功能 实现思路: 创建 Java 项目,在项目中创建服务端类 ChatServerThre ...

  9. 20个开发人员非常有用的Java功能代码

    本文将为大家介绍20个对开发人员非常有用的Java功能代码.这20段代码,可以成为大家在今后的开发过程中,Java编程手册的重要部分. 1. 把Strings转换成int和把int转换成String ...

随机推荐

  1. Docker理解

    近期一直在研究Docker,感悟颇深,和大家分享一下Docker 在云计算中的应用和Docker的原理. Docker 用法https://yeasy.gitbooks.io/docker_pract ...

  2. javascript设计模式——迭代器模式

    前面的话 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示.迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也 ...

  3. tensorflow 安装升级

    对于已经安装过的tensorflow,执行以下命令升级到最新版: pip3 install -U tensorflow 目前最新版本1.4

  4. Android数据绑定技二,企业级开发

    PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...

  5. Asp.net导出Excel/Csv文本格式数据

    刚刚开始做Excel相关的项目,所以遇到的问题不管大小都给记录一下 偶然的机会在添加数据的时候全改成了数字,结果输出的时候全自动变成了科学计数法,这是excel的强大功能,能自动识别数字和字符串,太聪 ...

  6. 两行 CSS 代码实现 PNG 任意颜色赋色技术

    很久之前在张鑫旭大大的博客看到过一篇 PNG格式小图标的CSS任意颜色赋色技术,当时惊为天人,感慨还可以这样玩,私底下也曾多次想过有没有其他方法可以实现. 本方法与上面 ZXX 的方法及流传的使用 f ...

  7. Chrome浏览器调试技巧

    本文主要讲解针对chrome浏览器的调试方案,对于其他浏览器其实大同小异. 先来入门一点的 DOM元素调试 看上图: 以上图表明的1,2,3,4,5标记说明: 1,为移动设备模拟器,chorme现在是 ...

  8. httpfs安装指南

    httpfs安装指南 安装环境 Linux maven3 jdk1.6 本地的maven源(有些依赖的jar包Cloudera已不再维护) 1.下载httfs源代码包 https://github.c ...

  9. 近期对FTP及Excel数据处理的一些摸索

    一个多月没写随笔了,主要是发的东西,自己感觉也很垃圾,说又说回来,谁不是从垃圾变强的,所以不比比,还得努力.come on!! Python学习也有段时间了,近期为了解决同事的一个难题,所以我们决定联 ...

  10. TP3.2.3 接入支付宝

    TP3.2.3 接入支付宝 项目接入支付宝支付了,在做这个给我的感觉是,方便 ,毕竟是老马的产品是吧, 话不多说 , 首先我们先找到官方的SDK  ,不想去找的小伙伴复制此链接 https://doc ...