udp 双机通信(服务器循环检测)2

此文摘自:http://blog.csdn.net/qinpeng100423/article/details/8980423,谢谢了

自己上一篇写的udp通信,只能运行一次,参考了这位博主的,只是把receive的方法处改为循环,这样即可实现服务器循环检测,然后接受数据和回复

受到项目要求,将文件分离,读者引用该类,实例化调用方法即可。

一. UDP协议定义

UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

二. 使用UDP的原因
它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和OICQ就是使用的UDP协议。在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人不十分满意的环境下,UDP协议数据包丢失会比较严重。

三. 在Java中使用UDP协议编程的相关类
1. InetAddress
用于描述和包装一个Internet IP地址。有如下方法返回实例:
getLocalhost():返回封装本地地址的实例。

getAllByName(String host):返回封装Host地址的InetAddress实例数组。

getByName(String host):返回一个封装Host地址的实例。其中,Host可以是域名或者是一个合法的IP地址。
InetAddress.getByAddress(addr):根据地址串返回InetAddress实例。
InetAddress.getByAddress(host, addr):根据主机地符串和地址串返回InetAddress实例。

2. DatagramSocket
用于接收和发送UDP的Socket实例。该类有3个构造函数:
DatagramSocket():通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。程序会让操作系统分配一个可用的端口。
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。通常用于服务端

DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。
DatagramSocket具有的主要方法如下:
1)receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。“阻塞”是一个专业名词,它会产生一个内部循环,使程序暂停在这个地方,直到一个条件触发。

2)send(DatagramPacket dp):发送报文dp到目的地。

3)setSoTimeout(int timeout):设置超时时间,单位为毫秒。

4)close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。

3. DatagramPacket
用于处理报文,它将Byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成Byte数组。应用程序在产生数据包是应该注意,TCP/IP规定数据报文大小最多包含65507个,通常主机接收548个字节,但大多数平台能够支持8192字节大小的报文。DatagramPacket类的构建器共有4个:
DatagramPacket(byte[] buf, int length):将数据包中Length长的数据装进Buf数组,一般用来接收客户端发送的数据。
DatagramPacket(byte[] buf, int offset, int length):将数据包中从Offset开始、Length长的数据装进Buf数组。
DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort):从Buf数组中,取出Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口,通常用来发送数据给客户端。

DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort):从Buf数组中,取出Offset开始的、Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口,通常用来发送数据给客户端。
主要的方法如下:
1)getData(): 从实例中取得报文的Byte数组编码。
2)setDate(byte[] buf):将byte数组放入要发送的报文中。



服务器端:

新建udpServer.java ,udpServer类代码:

package com.swust.udp;

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

/**
 * Copyright 2007 GuangZhou Cotel Co. Ltd.
 * All right reserved.
 * UTP服务类.
 * @author QPING
 */
public class UdpServerSocket {
    private byte[] buffer = new byte[1024];    

    private DatagramSocket ds = null;    

    private DatagramPacket packet = null;    

    private InetSocketAddress socketAddress = null;    

    private String orgIp;    

    /**
     * 构造函数,绑定主机和端口.
     * @param host 主机
     * @param port 端口
     * @throws Exception
     */
    public UdpServerSocket(String host, int port) throws Exception {
        socketAddress = new InetSocketAddress(host, port);
        ds = new DatagramSocket(socketAddress);
        System.out.println("服务端启动!");
    }    

    public final String getOrgIp() {
        return orgIp;
    }    

    /**
     * 设置超时时间,该方法必须在bind方法之后使用.
     * @param timeout 超时时间
     * @throws Exception
     */
    public final void setSoTimeout(int timeout) throws Exception {
        ds.setSoTimeout(timeout);
    }    

    /**
     * 获得超时时间.
     * @return 返回超时时间.
     * @throws Exception
     */
    public final int getSoTimeout() throws Exception {
        return ds.getSoTimeout();
    }    

    /**
     * 绑定监听地址和端口.
     * @param host 主机IP
     * @param port 端口
     * @throws SocketException
     */
    public final void bind(String host, int port) throws SocketException {
        socketAddress = new InetSocketAddress(host, port);
        ds = new DatagramSocket(socketAddress);
    }    

    /**
     * 接收数据包,该方法会造成线程阻塞.
     * @return 返回接收的数据串信息
     * @throws IOException
     */
    public final String receive() throws IOException {
        packet = new DatagramPacket(buffer, buffer.length);
        ds.receive(packet);
        orgIp = packet.getAddress().getHostAddress();
        String info = new String(packet.getData(), 0, packet.getLength());
        System.out.println("接收信息:" + info);
        return info;
    }    

    /**
     * 将响应包发送给请求端.
     * @param bytes 回应报文
     * @throws IOException
     */
    public final void response(String info) throws IOException {
        System.out.println("客户端地址 : " + packet.getAddress().getHostAddress()
                + ",端口:" + packet.getPort());
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length, packet
                .getAddress(), packet.getPort());
        dp.setData(info.getBytes());
        ds.send(dp);
    }    

    /**
     * 设置报文的缓冲长度.
     * @param bufsize 缓冲长度
     */
    public final void setLength(int bufsize) {
        packet.setLength(bufsize);
    }    

    /**
     * 获得发送回应的IP地址.
     * @return 返回回应的IP地址
     */
    public final InetAddress getResponseAddress() {
        return packet.getAddress();
    }    

    /**
     * 获得回应的主机的端口.
     * @return 返回回应的主机的端口.
     */
    public final int getResponsePort() {
        return packet.getPort();
    }    

    /**
     * 关闭udp监听口.
     */
    public final void close() {
        try {
            ds.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
    

此时,主函数处代码调用:

package com.swust.udp;

public class udpServer {     

    /**
     * 测试方法.
     * @param args
     * @throws Exception
     */
     public static void main(String[] args) throws Exception  {
        String serverHost = "127.0.0.1";
        int serverPort = 3344;
        UdpServerSocket udpServerSocket = new UdpServerSocket(serverHost, serverPort);
        while (true) {
            udpServerSocket.receive();
            udpServerSocket.response("你好,paopao,已收到!");    

        }
    }
}   



相应的,客户端代码:

新建udpClient.java ,udpClient类代码:

package com.swust.udp;

import java.io.*;
import java.net.*;    

/**
 * Copyright 2007 GuangZhou Cotel Co. Ltd.
 * All right reserved.
 * UDP客户端程序,用于对服务端发送数据,并接收服务端的回应信息.
 * @author QPING
 */
public class UdpClientSocket {
    private byte[] buffer = new byte[1024];    

    private DatagramSocket ds = null;    

    /**
     * 构造函数,创建UDP客户端
     * @throws Exception
     */
    public UdpClientSocket() throws Exception {
        ds = new DatagramSocket();
    }    

    /**
     * 设置超时时间,该方法必须在bind方法之后使用.
     * @param timeout 超时时间
     * @throws Exception
     */
    public final void setSoTimeout(final int timeout) throws Exception {
        ds.setSoTimeout(timeout);
    }    

    /**
     * 获得超时时间.
     * @return 返回超时时间
     * @throws Exception
     */
    public final int getSoTimeout() throws Exception {
        return ds.getSoTimeout();
    }    

    public final DatagramSocket getSocket() {
        return ds;
    }    

    /**
     * 向指定的服务端发送数据信息.
     * @param host 服务器主机地址
     * @param port 服务端端口
     * @param bytes 发送的数据信息
     * @return 返回构造后俄数据报
     * @throws IOException
     */
    public final DatagramPacket send(final String host, final int port,
            final byte[] bytes) throws IOException {
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress
                .getByName(host), port);
        ds.send(dp);
        return dp;
    }    

    /**
     * 接收从指定的服务端发回的数据.
     * @param lhost 服务端主机
     * @param lport 服务端端口
     * @return 返回从指定的服务端发回的数据.
     * @throws Exception
     */
    public final String receive(final String lhost, final int lport)
            throws Exception {
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
        ds.receive(dp);
        String info = new String(dp.getData(), 0, dp.getLength());
        return info;
    }    

    /**
     * 关闭udp连接.
     */
    public final void close() {
        try {
            ds.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

此时,客户端主函数:

package com.swust.udp;

public class udpClient {
    /**
     * 测试客户端发包和接收回应信息的方法.
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        UdpClientSocket client = new UdpClientSocket();
        String serverHost = "127.0.0.1";
        int serverPort = 3344;
        client.send(serverHost, serverPort, ("你好,服务器你一直在运行啊\nNB!").getBytes());
        String info = client.receive(serverHost, serverPort);
        System.out.println("服务端回应数据:" + info);
    }
}   

                                                                                                                                              2015-08-21于大学

时间: 2024-10-14 18:27:58

udp 双机通信(服务器循环检测)2的相关文章

基于Android硬件设备跟微信服务器通信的项目心得,以UDP Byte通信为例,建立无向连接,0530手札

这段时间挺忙的,微信企业号等微信系列的教程全部停滞了,原因是我手头上抓着几个项目,加班就不说了,今天刚刚把新接手的项目整到大概%80的样 子吧,准备明天整整,星期一过来直接对接测试,很多朋友跑过来问问题,我是真没时间,请见谅! 今天就分享下这个项目的总结,源码就不粘贴了,因为是商业项目,只是传达下编码思想,希望其他朋友在遇到类似项目的时候有个参考,不至于找不到 一点点思路 使用UDP进行通讯,每条指令不超过1024字节,所有多字节整形数据采用网络字节顺序传输.终端每上报一条指令,平台都将回复一条

高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.2

HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/C++.C#.Delphi.E(易语言).Java.Python 等编程语言接口.HP-Socket 对通信层实现完全封装,应用程序不必关注通信层的任何细节:HP-Socket 提供基于事件通知模型的 API 接口,能非常简单高效地整合到新旧应用程序中. 为了让使用者能方便快速地学习和使用 HP-S

高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.0.1 发布

HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/C++.C#.Delphi.E(易语言).Java.Python 等编程语言接口.HP-Socket 对通信层实现完全封装,应用程序不必关注通信层的任何细节:HP-Socket 提供基于事件通知模型的 API 接口,能非常简单高效地整合到新旧应用程序中. 为了让使用者能方便快速地学习和使用 HP-S

实现TCP、UDP相互通信及应用

实验名称  Socket编程综合实验(1) 一.实验目的: 1.理解进程通信的原理及通信过程 2.掌握基于TCP和UDP的工作原理 3.掌握基本的Socket网络编程原理及方法 二.实验内容 1.掌握简单的基于流式套接字的编程技术:如实现简单的聊天功能.实现简单的信息服务功能等等. 2.掌握简单的基于数据报式套接字的编程技术:如实现简单的聊天功能.实现简单的信息服务功能等等. 三.对所实现的功能进行描述,并附上相应的流程图. 1.基于流式套接字:可以通过选择,分别实现聊天.游戏:猜数字和应用:判

Java实现IO通信(服务器篇)

Java实现IO通信(服务器篇) 如何利用java实现我们的通信呢?首先我们了解一下什么是通信?通信的机制是怎样的? 首先来讨论一下什么是通信?通信,指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递,从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法,任意媒质,将信息从某方准确安全地传送到另方.而这里所说的通信,是在同一局域网内,一个用户给其他用户发送信息的过程. 然后通行的机制是怎么样的呢?这里的JavaIO通信是这样的,首先我们需要一台服务器,并有一个或者多个用户

UDP和多线程服务器

UDP: UDP是数据报文传输协议,这个传输协议比较野蛮,发送端不需要理会接收端是否存在,直接就发送数据,不会像TCP协议一样建立连接.如果接收端不存在的话,发送的数据就会丢失,UDP协议不会去理会数据的安全性,而且在网络繁忙.堵塞的时候会丢失一些数据,俗称"丢包". 但是UDP协议的传输速度很快,基本是你的网络有多快就传输多快.所以游戏.直播.语音电话等功能都是得靠UDP来实现 ,TCP都是基于UDP开发的,就是在UDP上增加了各种安全措施保护了数据的安全,牺牲了传输的速度. UDP

PHP 循环检测并生成目录 chkDir($dirname,$split='/')

自己写的,在MVC框架里面可以直接使用! /** * @author F.Z.B <[email protected]> * @description 循环检测目录 * * @param $dir * @param string $split * * @return bool */ function chkDir($dir, $split = '/') { preg_match_all('/([^\/]+)\/?/', str_replace('\\', '/', trim($dir)), $

linux服务器性能检测工具nmon使用

今天介绍一款linux系统服务器性能检测的工具-nmon及nmon_analyser (生成性能报告的免费工具),亲测可用. 一.介绍 nmon 工具可以帮助在一个屏幕上显示所有重要的性能优化信息,并动态地对其进行更新.这个高效的工具可以工作于任何哑屏幕.telnet 会话.甚至拨号线路.另外,它并不会消耗大量的 CPU 周期,通常低于百分之二.在更新的计算机上,其 CPU 使用率将低于百分之一. 使用哑屏幕,在屏幕上对数据进行显示,并且每隔两秒钟对其进行更新.然而,您可以很容易地将这个时间间隔

单片的双机通信

通常单片机的双机通信有以下4中方式通信: TTL电平通信(双机串行口直接互连).RS-232C通信.RS-422A通信.RS-485通信等. TTL电平通信时,单片机A的TXD端接单片机B的RXD端,单片机B的RXD端接B的TXD端.但是两个单片机的地线必须要共地,即把他们的系统电源地线要接在一起. 主机按键 #include <reg52.h> #define uchar unsigned char #define uint unsigned int void delayms(uint xm