问题
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?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/35797073/udp-client-written-in-golang-fails-to-receive-message-from-server