Java网络编程基础(三)---基于UDP编程

前面在介绍TCP/IP协议的时候我们已经提到,在TCP/IP协议的传输层除了TCP协议外还有一个UDP协议,相比UDP的应用不如TCP广泛,但是随着计算机网络的发展UDP协议正越来越显示出及其威力,尤其是在需要很强的实时交互性的场合,例如网络游戏和视频会议等,UDP更是显示出极强的威力。

UDP采用Datagram(数据报)传输,数据包是一种尽力而为的传送数据的方式,它只是 把数据的目的地记录在数据包中,然后就直接放在网络上,系统不保证数据是否能安全到达,或者什么时候可以送到,它并不保证传送质量。

Datagram(数据报)是网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址信息的消息,它能够到达目的地、到达时间、到达时内容是否会变化是不能准确知道的。它的通信双方不需要建立连接,对于一些不需要很高质量的应用程序来说,数据报通信是一个非常好的选择。还有就是对实时性很高的情况,比如在实时音频和视频应用中,数据包的丢失和位置是静态的,是可以被人们所忍受的,这时就可以利用UDP协议传输。

DatagramSocket(数据报套接字)工作包含了3个信息类:DatagramPacket、DatagramSocket和MulticastSocket。DatagramPacket对象描绘了数据报地址信息,DatagramSocket表示客户程序和服务程序报套接字,MulticastSocket描绘了能够进行多点传输的数据报套接字。

示例:利用数据报通信的Client/Server程序

(1)首先要建立数据报通信的Socket,我们可以通过创建一个DatagramSocket对象实现它

(2)创建一个数据报包,用来实现无连接的包传送服务。每个数据报包用DatagramPacket类创建,DatagramPacket对象封装了数据报包数据、包长度、目标地址和目标接口

(3)创建完DatagramSocket和DatagramPacket对象,就可以发送数据报包了。发送是通过调用DatagramSocket对象的send()方法实现的,它需要以DatagramPacket对象为参数,将刚才封装进DatagramPacket对象中的数据组成数据报发出。

(4)为了接收从服务器返回的结果数据报包,我们需要创建一个新的DatagramPacket对象,这就需要调用到DatagramPacket的另一个构造方式DatagramPacket(byte[] buffer,int length),即只需指明存放接收的数据报的缓存区和长度。调用DatagramSocket对象的receive()方法完成接收数据报的工作,此时需要将上面创建的DatagramPacket对象作为参数,该方法会一直阻塞,直到收到一个数据报包,

(5)处理接收缓存区内的数据,获取服务结果

(6)当通信完成后,可以使用DatagramSocket对象的close()方法关闭数据报通信Socket。

下面给出一个简单的利用数据报通信的服务器程序和客户端程序,它只能完成与服务器简单的通信。

a、服务器端程序

package org.test.socket.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * @author Administrator
 *
 */
public class UDPServer {
    public static void main(String[] args) {
        try {
            //创建Socket
            DatagramSocket socket = new DatagramSocket(12345);
            //创建接收包
            byte[] buf = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
            System.out.println("开始接收包....");
            
            //循环监听
            while(true){
                socket.receive(receivePacket);
                String name = receivePacket.getAddress().toString();
                System.out.println("来自主机:"+ name + "\n端口:"
                        +receivePacket.getPort());
                String s = new String(receivePacket.getData(),0,receivePacket.getLength());
                System.out.println("接收到数据:"+s);
            }
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

b、客户端程序

package org.test.socket;

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 UDPClient {

    public static void main(String[] args) {
        try {
            // 创建Socket
            DatagramSocket socket = new DatagramSocket();
            
            //创建发送包
            InetAddress host = InetAddress.getByName("localhost");
            String msg = "hello,I‘m client";
            DatagramPacket sendPacket = new DatagramPacket(msg.getBytes(), msg.length(),host,12345);
            
            //发送数据
            socket.send(sendPacket);
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

c、运行结果:

开始接收包....
来自主机:/127.0.0.1
端口:51240
接收到数据:hello,I‘m client

d、这只是演示udp通信方式,以上方式也可改为双方通信

组播套接字MulticastSocket

DatagramSocket只允许数据报发送一个目的地址,MulticastSocket允许数据报以广播的形式发送到该端口的所有客户。

多播数据报套接字用于发送和接收IP多播包。MulticastSocket是一种DatagramSocket,它具有加入Internet上其他多播主机的组的附加功能。

组播套接字和Client/Server程序

服务器端程序。

package org.test.socket.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

public class MultiServer {

    public static void main(String[] args) {
        try {
            // TODO 创建Socket
            MulticastSocket socket = new MulticastSocket(12345);
            InetAddress group = InetAddress.getByName("231.0.0.0");
            socket.joinGroup(group);
            
            //接收数据报
            for(int i = 0;i<100;i++){
                byte[] buf = new byte[256];
                DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
                socket.receive(receivePacket);
                
                //去除空格
                byte[] buf2 = new byte[receivePacket.getLength()];
                System.arraycopy(receivePacket.getData(), 0, buf2, 0, receivePacket.getLength());
                System.out.println(new String(buf2));
            }
            //删除组播地址
            socket.leaveGroup(group);
            socket.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

客户端程序

package org.test.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

public class MultiClient {

    public static void main(String[] args) {
        try {
            // 创建Socket
            MulticastSocket socket = new MulticastSocket();
            InetAddress group = InetAddress.getByName("231.0.0.0");
            
            //创建发送数据包
            byte[] buf = new byte[0];
            DatagramPacket sendPacket = new DatagramPacket(buf, 0, group, 12345);
            
            //发送数据
            for(int i = 0;i < 5;i ++){
                byte[] buf1 = ("Data line" + i).getBytes();
                sendPacket.setData(buf1);
                sendPacket.setLength(buf1.length);
                socket.send(sendPacket);
            }
            socket.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

}
时间: 2024-12-21 13:17:10

Java网络编程基础(三)---基于UDP编程的相关文章

嵌入式 Linux网络编程(三)——UDP编程模型

嵌入式 Linux网络编程(三)--UDP编程模型 UDP编程模型: UDP循环服务器模型为: socket(...); bind(...); while(1) {    recvfrom(...);    process(...);    sendto(...); } server.c代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #inc

62 网络编程(三)——UDP编程

UDP编程标准步骤 服务器端 使用DatagramSocket创建服务端:DatagramSocket server = new DatagramSocket(port);//参数为自定义端口号 准备接受容器1:必须是byte数组 使用DatagramPacket创建接受容器2:DatagramPacket packet = new DatagramPacket(容器1,start,length);//容器2的名字写为了packet 接受数据:serve.receive(packet); 处理数

java网络爬虫基础学习(三)

尝试直接请求URL获取资源 豆瓣电影 https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=time&page_limit=20&page_start=0 浏览器打开该地址: 发现是这样的 在这里我们需要用java抓取电影的信息,首先要找到资源链接,浏览器右键->检查打开谷歌调试工具 我们可以看到下图 有很多的资源请求,在这里我是一个个搜索,看那个是电影信息的Headers 发

[.net 面向对象编程基础] (2) 关于面向对象编程

[.net 面向对象编程基础]  (2)  关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问题来了什么是对象,不是“女盆友”“找对象”的这个对象.当然也可以理解“女盆友”也是“对象”的一种. 面向对象中的对象,指一切皆是对象 专业述语解释我们无视就好 只所有面向对象编程,是因为之前有一个面向过程编程 面向过程——是指把问题分解成步骤,一步一步实现 面向对象——是把构成问题的事务分成各个对象

java网络爬虫基础学习(一)

刚开始接触java爬虫,在这里是搜索网上做一些理论知识的总结 主要参考文章:gitchat 的java 网络爬虫基础入门,好像要付费,也不贵,感觉内容对新手很友好. 一.爬虫介绍 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网下载网页,是搜索引擎的重要组成部分. 传统爬虫: 获得URL ->放入队列 ->抓取网页,分析信息 ->新的URL ->放入队列 ->抓取网页,分析信息... ->满足一定条件,停止. 聚焦爬虫: 根据一定的网页分析算法过滤与主题无关的链接

网络编程[第二篇]基于udp协议的套接字编程

udp协议下的套接字编程 一.udp是无链接的    不可靠的 而上篇的tcp协议是可靠的,会有反馈信息来确认信息交换的完成与否 基于udp协议写成的服务端与客户端,各司其职,不管对方是否接收到信息,只需自己发送了即可 二.客户端 import socket #买手机 -- 套接字家族 | 端口协议 phone = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #服务端地址 ip_port = ('127.0.0.1',8001) #实现多次发送

C/C++网络编程6——实现基于UDP的服务器端/客户端

前面介绍了基于TCP实现的服务器端和客户端,本节介绍基于UDP实现的服务器端和客户端.UDP协议提供的无连接的,不可靠的传输服务,在一些要求传输速度,可以接受丢包的传输场景应用广泛,比如视频音频传输场景.UDP中只有创建套接字的过程和数据交换的过程. #include <sys/socket.h> sszie_t sendto(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrl

网络骇客入门之UDP编程

本文列出了在LINUX系统下使用C语言进行UDP收发操作的常用函数和用法 注意: 创建套接字时,系统会分配一个临时端口,默认主动发起服务请求,作为服务器时可修改为被动 发送数据时,不需要用bind绑定端口(当然绑定也可以) 接收数据时,如果不想知道发送者的信息(如:IP地址,端口等),可以不创建发送者结构体,然后recvfrom的后两个参数写NULL 因为网络上的字节序是大端格式(低地址存高字节),所以在发送数据和显示接收的数据时要用htonl/htons和ntohl/ntohs转换(即host

Java网络编程之TCP、UDP

Java网络编程提供了两种协议:TCP(传输控制协议)和UDP(数据报协议).TCP(Transmission Control Protocol)是一种可靠的传输协议,传输时会采用"三次握手"端的方式建立连接,以保证数据的可靠性和安全性:而UDP(User Datagram Protocol)协议是一种不可靠的传输协议,发送的数据不一定能够接受的到,网上的聊天是工具一般采用的此协议.下面将详细的接受TCP和UDP的使用以及相应的编码. 一.TCP网络通信 Java中使用Socket(套