JAVA问题 UDP协议中的端口问题

JAVA问题 UDP协议中的端口问题,第1张

在Java中 *** 纵UDP
使用位于JDK中Javanet包下的DatagramSocket和DatagramPacket类,可以非常方便地控制用户数据报文
在描述它们之前,必须了解位于同一个位置的InetAddress类。InetAddress实现了Javaio Serializable接口,不允许继承。它用于描述和包装一个Internet IP地址,通过三个方法返回InetAddress实例:
getLocalhost():返回封装本地地址的实例。
getAllByName(String host):返回封装Host地址的InetAddress实例数组
getByName(String host):返回一个封装Host地址的实例。其中,Host可以是域名或者是一个合法的IP地址。
DatagramSocket类用于创建接收和发送UDP的Socket实例。和Socket类依赖SocketImpl类一样,DatagramSocket类的实现也依靠专门为它设计的DatagramScoketImplFactory类。DatagramSocket类有3个构建器:
DatagramSocket():创建实例。这是个比较特殊的用法,通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。
DatagramSocket(int port):创建实例,并固定监听Port端口的报文
DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。
值得注意的是,在创建DatagramSocket类实例时,如果端口已经被使用,会产生一个SocketException的异常抛出,并导致程序非法终止,这个异常应该注意捕获。DatagramSocket类最主要的方法有4个:
Receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。
Send(DatagramPacket d):发送报文d到目的地。
SetSoTimeout(int timeout):设置超时时间,单位为毫秒。
Close():关闭DatagramSocket。在应用程序退出的 焙颍�ǔ;嶂鞫�头抛试矗�乇誗ocket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。
“阻塞”是一个专业名词,它会产生一个内部循环,使程序暂停在这个地方,直到一个条件触发。
DatagramPacket类用于处理报文,它将Byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成Byte数组。应用程序在产生数据包是应该注意,TCP/IP规定数据报文大小最多包含65507个,通常主机接收548个字节,但大多数平台能够支持8192字节大小的报文。DatagramPacket类的构建器共有4个:
DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从Buf数组中,取出Length长的数据创建数据包对象,目标是Addr地址,Port端口。
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从Buf数组中,取出Offset开始的、Length长的数据创建数据包对象,目标是Addr地址,Port端口。
DatagramPacket(byte[] buf, int offset, int length):将数据包中从Offset开始、Length长的数据装进Buf数组。
DatagramPacket(byte[] buf, int length):将数据包中Length长的数据装进Buf数组。
DatagramPacket类最重要的方法就是getData()了,它从实例中取得报文的Byte数组编码。

我把我的代码借鉴给你不知道能不能够帮助你!!!自己原创的
UDPServerjava:
import javanet;
import javautil;
public class UDPServer extends Thread {
private static final int PORT=10000 ;
private static final int DATA_LEN=2046 ;
private byte []buff =new byte[DATA_LEN];
UDPClientjava:
import javanet;
import javautil;
public class UDPClient extends Thread {
private static final int PORT=10000 ;
private static final int DATA_LEN=2046 ;
private byte []buff =new byte[DATA_LEN];
private DatagramSocket socket ;
private DatagramPacket inpacket =new DatagramPacket(buff,bufflength);
private DatagramPacket outpacket ;
public void run() {
int i =0;
try{
socket=new DatagramSocket();
outpacket =new DatagramPacket(new byte[0] ,0,
InetAddressgetByName("127001"),PORT);
Scanner sc =new Scanner(Systemin);
while(schasNextLine()){
byte [] buff1 =scnextLine()getBytes();
outpacketsetData(buff1);
socketsend(outpacket);
socketreceive(inpacket);
Systemoutprintln(new String(buff,0,inpacketgetLength()));
}
}catch(Exception e){
eprintStackTrace();
}
}

public static void main(String []args){
new UDPClient()start();
}
/public UDPServer (DatagramSocket socket ,DatagramPacket inpacket,
DatagramPacket outpacket) {
thissocket = socket ;
thisinpacket = inpacket ;
thisoutpacket = outpacket ;
}/
};
MulticastSocketTestjava:
import javaawt;
import javanet;
import javaio;
import javautil;
//让该类实现Runnable接口,该类的实例可作为线程的target
public class MulticastSocketTest implements Runnable
{
//使用常量作为本程序的多点广播IP地址
private static final String BROADCAST_IP
= "230001";
//使用常量作为本程序的多点广播目的的端口
public static final int BROADCAST_PORT = 30000;
//定义每个数据报的最大大小为4K
private static final int DATA_LEN = 4096;
//定义本程序的MulticastSocket实例
private MulticastSocket socket = null;
private InetAddress broadcastAddress = null;
private Scanner scan = null;
//定义接收网络数据的字节数组
byte[] inBuff = new byte[DATA_LEN];
//以指定字节数组创建准备接受数据的DatagramPacket对象
private DatagramPacket inPacket =
new DatagramPacket(inBuff , inBufflength);
//定义一个用于发送的DatagramPacket对象
private DatagramPacket outPacket = null;
public void init()throws IOException
{
try
{
//创建用于发送、接收数据的MulticastSocket对象
//因为该MulticastSocket对象需要接收,所以有指定端口
socket = new MulticastSocket(BROADCAST_PORT);
broadcastAddress = InetAddressgetByName(BROADCAST_IP);
//将该socket加入指定的多点广播地址
socketjoinGroup(broadcastAddress);
//设置本MulticastSocket发送的数据报被回送到自身
socketsetLoopbackMode(false);
//初始化发送用的DatagramSocket,它包含一个长度为0的字节数组
outPacket = new DatagramPacket(new byte[0] , 0 ,
broadcastAddress , BROADCAST_PORT);
//启动以本实例的run()方法作为线程体的线程
new Thread(this)start();
//创建键盘输入流
scan = new Scanner(Systemin);
//不断读取键盘输入
while(scanhasNextLine())
{
//将键盘输入的一行字符串转换字节数组
byte[] buff = scannextLine()getBytes();
//设置发送用的DatagramPacket里的字节数据
outPacketsetData(buff);
//发送数据报
socketsend(outPacket);
}
}
finally
{
socketclose();
}
}

public void run()
{
try
{
while(true)
{
//读取Socket中的数据,读到的数据放在inPacket所封装的字节数组里。
socketreceive(inPacket);
//打印输出从socket中读取的内容
Systemoutprintln("聊天信息:" + new String(inBuff , 0 ,
inPacketgetLength()));
}
}
//捕捉异常
catch (IOException ex)
{
exprintStackTrace();
try
{
if (socket != null)
{
//让该Socket离开该多点IP广播地址
socketleaveGroup(broadcastAddress);
//关闭该Socket对象
socketclose();
}
Systemexit(1);
}
catch (IOException e)
{
eprintStackTrace();
}
}
}
public static void main(String[] args)
throws IOException
{
new MulticastSocketTest()init();
}
}
private DatagramSocket socket ;
private DatagramPacket inpacket ;
private DatagramPacket outpacket ;
public void run() {
int i =0;
try{
socket=new DatagramSocket(PORT);
while(true){
inpacket=new DatagramPacket(buff,bufflength);
socketreceive(inpacket) ;
Systemoutprintln(new String(buff,0,inpacketgetLength()));
byte [] sedData =new String("数据信息:"+i)getBytes();
outpacket =new DatagramPacket(sedData,sedDatalength,inpacketgetSocketAddress());
socketsend(outpacket);
i++ ;
}
}catch(Exception e){
eprintStackTrace();
}
}

public static void main(String []args){
new UDPServer()start();
}
/public UDPServer (DatagramSocket socket ,DatagramPacket inpacket,
DatagramPacket outpacket) {
thissocket = socket ;
thisinpacket = inpacket ;
thisoutpacket = outpacket ;
}/
};

//发送端SocketSendFilejava
import javaio;
import javanet;
public class SocketSendFile {
public static final int SER_PORT=666;
public static final int CLI_PORT=8484;
public static final String SER_IP="192168035";
public static int bufSize = 1024;
public static byte] mess = new bytebufSize];
//建立Socket引用
public static DatagramSocket dp;
public static void main(String] args) throws Exception {
dp = new DatagramSocket(SER_PORT);
//调用构造函数SocketSendFile,并传递参数args0](所要传输的文件名)
SocketSendFile(args0]);
}
public static void SocketSendFile(String file2) throws Exception {
//定义一个计数器
int pos =0;
//设置写入流
FileInputStream fis = new FileInputStream(file2);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int i;
do {
i = disread();
int j=0;
while (j<1024 & i != -1) {
messpos++] = (byte) i;
i=disread();
j++;
}
dpsend(new DatagramPacket(mess,pos,InetAddressgetByName(SER_IP),CLI_PORT));
}
while (i != -1);
fisclose();
}
}
//接收端SocketReceiveFilejava
import javanet;
import javaio;
public class SocketReceiveFile {
public static int bufSize=1024;
public static byte] mess=new bytebufSize];
public static DatagramSocket dp;
public static final int SER_PORT=8484;
public static void main(String] args) throws Exception {
dp = new DatagramSocket(SER_PORT);
SocketReceiveFile(args0]);
}
public static void SocketReceiveFile(String file1) throws Exception {
FileOutputStream fos = new FileOutputStream(file1);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos);
int i;
DatagramPacket p = new DatagramPacket(mess,messlength);
while(true) {
boolean j=false;
while (pgetData()length != 0) {
doswrite(pgetData());
dpreceive(p);
j=true;
}
// Systemoutprintln(new String(pgetData(),0,pgetLength()));
if (j)
Systemoutprintln("文件传送完毕.");
}
// fosclose();
}
}

创建两个类 分别添加main方法 一个作为server类一个作为client类

客户端先发送再接收  服务器端先接收再发送

下面给你一个server和client的例子 你在基础上改一下就行了

client发送的时候发送三边值  server接收后 写一个计算三角形面积的函数 把接收到的三边值传入函数计算出结果作为数据返回到client端

/
 UDPServer
 /
import javaio;
import javanet;
class UDPServer{
    public static void main(String[] args)throws IOException{
        DatagramSocket  server = new DatagramSocket(5050);
        byte[] recvBuf = new byte[100];
        DatagramPacket recvPacket 
            = new DatagramPacket(recvBuf , recvBuflength);
        serverreceive(recvPacket);
        String recvStr = new String(recvPacketgetData() , 0 , recvPacketgetLength());
        Systemoutprintln("Hello World!" + recvStr);
        int port = recvPacketgetPort();
        InetAddress addr = recvPacketgetAddress();
        String sendStr = "Hello ! I'm Server";
        byte[] sendBuf;
        sendBuf = sendStrgetBytes();
        DatagramPacket sendPacket 
            = new DatagramPacket(sendBuf , sendBuflength , addr , port );
        serversend(sendPacket);
        serverclose();
    }
}/
 UDPClient
 /
import javaio;
import javanet;
class UDPClient{
    public static void main(String[] args)throws IOException{
        DatagramSocket client = new DatagramSocket();
        
        String sendStr = "Hello! I'm Client";
        byte[] sendBuf;
        sendBuf = sendStrgetBytes();
        InetAddress addr = InetAddressgetByName("127001");
        int port = 5050;
        DatagramPacket sendPacket 
            = new DatagramPacket(sendBuf ,sendBuflength , addr , port);
        clientsend(sendPacket);
        byte[] recvBuf = new byte[100];
        DatagramPacket recvPacket
            = new DatagramPacket(recvBuf , recvBuflength);
        clientreceive(recvPacket);
        String recvStr = new String(recvPacketgetData() , 0 ,recvPacketgetLength());
        Systemoutprintln("收到:" + recvStr);
        clientclose();
    }
}

你说的还不清楚。Java网络编程使用Socket,同为一个网络下的主机时是肯定没问题的,不论同一局域网或广域网。如果内网跨越网关,我没做过试验,按我的理解,内网主机做客户端,独立主机做服务器应该可行,反之不行。

TCP是面向连接,UDP面向非连接,资料不复制,在这里简单说下:\x0d\TCP建立连接时需要传说的三次握手,服务端与客户端需要确认对方身份而已,建立好连接后,就开始传递消息,直到有一方断开连接位置。 就好比两个人打电话,要先通了才能说话。\x0d\UDP只是数据报发送,它的优点速度快,并非要向TCP那样麻烦建立,它只负责将信息发出,但是并不确保信息的准确完整性等,就好比发短信,短信是出去了,但是中间是否有问题,是否对方手机能收到就不管了。\x0d\在java中想要实现上述两种协议通信,可采用socket建立连接,socket可以理解为码头,其实是套接字,这里简单说下,就好比两个城市运输货物,通过码头走货一样。至于如何通过socket建立两个连接,网上资料多的是,在这里不复制例子了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13490908.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-08-17
下一篇 2023-08-17

发表评论

登录后才能评论

评论列表(0条)

保存