Java:通过 TCP 发送/接收数据并从 UDP 接收图像

Posted

技术标签:

【中文标题】Java:通过 TCP 发送/接收数据并从 UDP 接收图像【英文标题】:Java: send/receive data through TCP and receive image from UDP 【发布时间】:2021-12-14 01:22:12 【问题描述】:

我正在编写来自 C# 的代码,并试图在 java 中引用它。 基本上在第一步中,我通过 TCP 向 IP 摄像机发送和接收一些数据命令(这已完成),在第二步中,我必须通过 UDP 接收图像。问题出在第二步:从 UDP 接收图像。 我尝试了互联网上的所有代码,但没有一个工作。

原来的C#代码是这样的:

*C#中的服务器连接示例

    Socket _ServerUdp = null; 
    Socket _ServerTcpIp = null; 
    IPEndPoint _EndpointUdp = null; 
    TcpClient _ClientUdp; 
    /// <summary> 
    /// Connect the socket 
   /// <summary> 
    public bool Connect(string IpAddr) 
     
         if (!_VideoPortConnect(IpAddr, 8501)) 
                return false; 
        if (!_CommandPortConnect(IpAddr, 8500)) 
            return false; 
        return true; 
     
    /// <summary> 
    /// Udp Connect 
    /// </summary> 
    bool _VideoPortConnect(string IpAddr, int VideoPort) 
     
        try 
         
            _ServerUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
            _EndpointUdp = new IPEndPoint(IPAddress.Parse(IpAddr), VideoPort); 
            _ClientUdp = new TcpClient(); 
            _ClientUdp.Connect(_EndpointUdp); 
            return true; 
         
        catch  return false;  
     

    /// <summary> 
    /// Tcp Ip Connect 
    /// </summary> 
    bool _CommandPortConnect(string IpAddr, int CommandPort) 
     
        _ServerTcpIp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
        IPEndPoint _RemoteEndPoint = new IPEndPoint(IPAddress.Parse(IpAddr), CommandPort); 
        _ServerTcpIp.ReceiveTimeout = 5000; 
        _ServerTcpIp.SendTimeout = 5000; 
        try 
         
            _ServerTcpIp.Connect(_RemoteEndPoint); 
            return true; 
         
        catch  return false;  
    ** 

发送命令和接收图像示例 该命令将通过 TCP/IP 发送。

byte[] DataReceived = 新字节[20000];

    /// <summary> 
    /// Send Command Bar Code Reader 
    /// </summary> 
    /// <returns></returns> 
    bool SendCommand() 
     
        byte[] _Send = new byte[3]; 
        _Send[0]= 20;    //CMD BAR CODE READER 
        _Send[1] = 2;    //EXT CMD GET DATA 
        _Send[2] = 2;    //SEND IMAGE 
        if (!SendEth(_Send, 3)) 
            return false; 
        int _Ndati = ReadEth(); 
        if (_Ndati == -1) 
            return false; 
        if (DataReceived[4] != 20) 
            return false; 
        GetImage(); 
     
    /// <summary> 
    /// Send Data 
    /// </summary> 
    /// <param name="_Val"></param> 
    /// <param name="_Len"></param> 
    bool SendEth(byte[] _Val, Int32 _Len) 
     
        try 
         
            byte[] _Send = new byte[_Len + 4]; 
            int _Value = _Len; 
            Array.Copy(_Val, 0, _Send, 4, _Len); 
            _Send[3] = (byte)_Value; 
            _Value <<= 8; 
            _Send[2] = (byte)_Value; 
            _Value <<= 8; 
            _Send[1] = (byte)_Value; 
            _Value <<= 8; 
            _Send[0] = (byte)_Value; 
            _ServerTcpIp.Send(_Send, _Len + 4, SocketFlags.None); 
         
        catch  return false;  
        return true; 
    
    /// <summary> 
    /// Read Data from Ethernet 
    /// </summary> 
    /// <param name="LenDati"></param> 
    /// <returns>array dati</returns> 
    internal int ReadEth() 
     
        int _Ndati; 
        try 
         
            _Ndati = _ServerTcpIp.Receive(DataReceived, SocketFlags.None); 
            DataPointer =0; 
            int _Len = GetInt(); 
            if(_Len!=_Ndati-4) 
             
                int _Diff = (_Ndati - 4) - _Len; 
                byte[] BuffRx = new byte[_Diff]; 
                int _NrDati = 0; 
                int _PuntRx = _Ndati; 
                while (_PuntRx < _Diff) 
                 
                    _NrDati = _ServerTcpIp.Receive(BuffRx, _Diff, SocketFlags.None); 
                    for (int n = 0; n < _NrDati; n++) 
                        DataReceived[_PuntRx++] = BuffRx[n]; 
                 
             
            return _Ndati; 
         

        catch  return -1;  
     

    /// <summary> 
    /// Get Image 
    /// </summary> 
    /// <returns></returns> 
    internal ImageSource GetImage() 
     
        //get image 
        NetworkStream _Stream = _ClientUdp.GetStream(); 
        byte[] _Data = (byte[])_Formatter.Deserialize(_Stream); 
        MemoryStream _ImgStream = new MemoryStream(_Data); 
        ImageSource _Image = BitmapFrame.Create(_ImgStream, BitmapCreateOptions.None, 
        BitmapCacheOption.OnLoad); 
        return _Image; 
     

我的 JAVA 代码:

公共类 TFinale

static byte[] DataReceived = new byte[20000];

public static void main(String[] args) throws Exception 
    String[] args8500 = new String[2];
    args8500[0] = "10.0.0.123";
    args8500[1] = "8500";
    int port8500 = Integer.parseInt(args8500[1]);

    String[] args8501 = new String[2];
    args8501[0] = "10.0.0.123";
    args8501[1] = "8501";
    int port8501 = Integer.parseInt(args8501[1]);

    Socket clientSocket8501 = TFinale.createSocket(args8501[0], port8501);
    if (clientSocket8501 == null) 
    System.err.println("Unable to create socket to " + args8501[0] + ":" + port8501 + ".");
    System.exit(1);
    
    Socket clientSocket8500 = TFinale.createSocket(args8500[0], port8500);

    if (clientSocket8500 == null) 
        System.err.println("Unable to create socket to " + args8500[0] + ":" + port8500 + ".");
        System.exit(1);
    

    byte[] _Send = new byte[3];
    _Send[0] = 22;    //CMD BAR CODE READER 
    _Send[1] = 2;    //EXT CMD GET DATA 
    _Send[2] = 2;    //SEND IMAGE
    int _Len1 = 3;
    byte[] SendEth1 = SendEth(_Send, _Len1);

    DataOutputStream serverOut = null;
    try 
        serverOut = new DataOutputStream(clientSocket8500.getOutputStream());
        serverOut.write(SendEth1, 0, 7);
        System.out.println("serverOut writed!");
     catch (IOException ex) 
        Logger.getLogger(TFinale.class.getName()).log(Level.SEVERE, null, ex);
    
    DataInputStream in = null;
    try 
        byte[] messageByte = new byte[1000];
        boolean end = false;
        String dataString = "";
        in = new DataInputStream(clientSocket8500.getInputStream());
        int bytesRead = 0;
        int f = 0;
        //System.out.println("Please type 8500 clientSocket......");
        for (f = 0; f < 7; f++) 
            messageByte[f] = in.readByte();
            System.out.println("messageByte 8500[" + f + "] " + messageByte[f]);
        
        ByteBuffer byteBuffer = ByteBuffer.wrap(messageByte, 0, f);
        int bytesToRead = byteBuffer.getShort();
        System.out.println("About to read " + bytesToRead + " octets");
     catch (IOException ex) 
        Logger.getLogger(TCPClient1.class.getName()).log(Level.SEVERE, null, ex);
     finally 
        try 
            in.close();
         catch (IOException ex) 
            Logger.getLogger(TCPClient1.class.getName()).log(Level.SEVERE, null, ex);
        
    
    timeDelay(1000);
    try 
        serverOut.close();
        System.out.println("serverOut closed!");
        in.close();
        System.out.println("in closed!");
        clientSocket8501.close();
        System.out.println("clientSocket8501 closed!");
        clientSocket8500.close();
        System.out.println("clientSocket8500 closed!");
     catch (IOException ex) 
        System.out.println("error:" + ex);
    



private static Socket createSocket(final String hostname, final int port) 
    try 
        Socket clientSocket = new Socket(hostname, port);
        System.out.println(hostname + ":" + port + " socket created!");
        return clientSocket;
     catch (UnknownHostException e) 
        System.err.println(" " + hostname + " cannot be resolved as a network host.");
        return null;
     catch (IOException e) 
        System.err
                .println("An exception occurred while communicating with the TCPServer: "
                        + e.getMessage());
        e.printStackTrace();
        return null;
    



private static void timeDelay(int i) 
    try 
        Thread.sleep(i);
     catch (InterruptedException e) 
    


private static byte[] SendEth(byte[] _Val, int _Len) 
    byte[] _Send = new byte[_Len + 4];
    int _Value = _Len;
    System.arraycopy(_Val, 0, _Send, 4, _Len);
    //Array.Copy(_Val, 0, _Send, 4, _Len); 
    _Send[3] = (byte) _Value;
    _Value <<= 8;
    _Send[2] = (byte) _Value;
    _Value <<= 8;
    _Send[1] = (byte) _Value;
    _Value <<= 8;
    _Send[0] = (byte) _Value;
    return _Send;




谢谢大家帮帮我!

【问题讨论】:

“它不起作用”对于任何人来说都没有足够的调试信息来提供帮助。发生什么了?这与您的预期有何不同? FWIW,这似乎会混淆问题:TcpClient _ClientUdp; 所以我们有一个以 UDP 命名的对象,它显然是用于 TCP 的类型。我们使用的是 TCP 还是 UDP?我的猜测是 TCP,理由是使用 UDP 处理大数据似乎有点傻。 我在互联网上尝试了许多代码显示来监听地址:8501 中的 udp,但在发送命令期间没有收到任何内容... 【参考方案1】:

@Federico111,您应该使用java.net.DatagramSocket 而不是Socket 来使用UDP。

【讨论】:

以上是关于Java:通过 TCP 发送/接收数据并从 UDP 接收图像的主要内容,如果未能解决你的问题,请参考以下文章

UDP/TCP 发送和接收,无需端口转发

UDP和TCP的区别

TCP UDP之间的区别

Java将udp数据包发送到dns服务器

如何通过 UDP 发送实时数据?

UDP与TCP协议