duangu1033 2016-03-04 13:16
浏览 204
已采纳

用Golang编写的UDP客户端无法从服务器接收消息

I have written a Java Client, which sends a message to the broadcast address.

I have also written a Java Server, which accepts all sent messages and sends the message back to the client.

Now I wanted to try to do exactly the same in Go, just for gaining some experience. The server works fine and is receiving a message and responding to the Java client.

But my Go Client is only sending a message to the Go/Java server but does not receive any message back. According to wireshark the message is sent back to the right IP and Port, but apparently the port is unreachable.

My Code is as follows: Go Server:

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    //Resolving address
    udpAddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:8888")

    if err != nil {
        log.Println("Error: ", err)
    }

    // Build listining connections
    conn, err := net.ListenUDP("udp", udpAddr)

    defer conn.Close()

    if err != nil {
        log.Println("Error: ", err)
    }

    // Interacting with one client at a time
    for {
        fmt.Println(">>>Ready to receive broadcast packets!")

        // Receiving a message
        recvBuff := make([]byte, 15000)
        _, rmAddr, err := conn.ReadFromUDP(recvBuff)

        if err != nil {
            panic(err)
        }

        fmt.Println(">>>Discovery packet received from: " + rmAddr.String())
        fmt.Println(">>>Packet received; data: " + string(recvBuff))

        // Sending the same message back to current client
        conn.WriteToUDP(recvBuff, rmAddr)

        fmt.Println(">>>Sent packet to: " + rmAddr.String())

} }

Go Client:

package main

import (
    "fmt"
    "log"
    "net"
    "os"
)

func main() {
    service := "158.129.239.255:8888"

    // Resolving Address
    RemoteAddr, err := net.ResolveUDPAddr("udp", service)

    // Make a connection
    conn, err := net.DialUDP("udp", nil, RemoteAddr)

    defer conn.Close()

    // Exit if some error occured
    if err != nil {
        log.Fatal(err)
        os.Exit(1)
    }

    // write a message to server
    message := []byte("message")

    _, err = conn.Write(message)
    fmt.Println(">>> Request packet sent to: 158.129.239.255 (DEFAULT)")

    if err != nil {
        log.Println(err)
    }

    // Receive response from server
    buf := make([]byte, 15000)
    amountByte, remAddr, err := conn.ReadFromUDP(buf)

    if err != nil {
        log.Println(err)
    } else {
        fmt.Println(amountByte, "bytes received from", remAddr)
    }

}

Java Client:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;

public class BroadcastUDPClient {

    public static void main(String[] args) {
        // Find the server using UDP broadcast
        try {
            //Open a random port to send the package
            DatagramSocket sendSD = new DatagramSocket();
            sendSD.setBroadcast(true);

                byte[] sendData = "message".getBytes();

            //Try the 255.255.255.255 first
            try {
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("158.129.239.255"), 8888);
                sendSD.send(sendPacket);
                System.out.println(">>> Request packet sent to: 158.129.239.255 (DEFAULT)");
            } catch (Exception e) {
            }

            //Wait for a response
            byte[] recvBuf = new byte[15000];
            DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
            sendSD.receive(receivePacket);

            //We have a response
            System.out.println(">>> Broadcast response from server: " + receivePacket.getAddress().getHostAddress());
            String message = new String(receivePacket.getData()).trim();
            System.out.println(">>> Message Body: " + message);

            //Close the port!
            sendSD.close();
        } catch (IOException ex) {
            Logger.getLogger(BroadcastUDPClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

What am I doing wrong with my Go Client?

  • 写回答

2条回答 默认 最新

  • dsfg3241 2016-03-04 19:53
    关注

    Even if you're you're only going to be sending UDP packets from the connection, you generally want to use ListenUDP to create the connection, and use the ReadFromUDP and WriteToUDP methods.

    When you use DialUDP, it creates a "connected" UDP socket, with an implicit remote endpoint, which will filter incoming packets. From the Linux connect man page:

    If the socket sockfd is of type SOCK_DGRAM then addr is the address to which datagrams are sent by default, and the only address from which datagrams are received.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • duanlun2827 2016-03-04 16:46
    关注

    If you don't ignore the error you get back from WriteToUDP it will actually give you an error: "sendto: message to long"

    On OSX the the maximum UDP Datagram size is set default to 9216 bytes. You try to send 15000 bytes.

    If you just want to write back what you received then write

    recvBuff[:n]
    

    , where n is the number of bytes received before.

    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 宾馆客房管理系统可视化
  • ¥20 unity打光没有照亮物体
  • ¥25 powershell如何拷贝1周前的文件
  • ¥15 询问MYSQL查询SQLSERVER数据表并比较差异后,更新MYSQL的数据表
  • ¥15 关于#前端#的问题,请各位专家解答!
  • ¥15 最小生成树问题 Prim算法和Kruskal算法
  • ¥25 医院住院病人呼叫器设计
  • ¥15 不想和现在的团队合作了,怎么避免他们对程序动手脚
  • ¥20 C语言字符串不区分大小写字典排序相关问题
  • ¥15 关于#python#的问题:我希望通过逆向技术爬取1688搜索页下滑加载的数据