UDP communication between Java and C# - java

I'm trying to communicate a Java program with a C# one but it's not working.
The code is really basic, here it is:
This is the Java client
static InetAddress ip;
static int port = 10000;
public static void main(String args[]) {
try {
ip = InetAddress.getByName("127.0.0.1");
DatagramSocket socket = new DatagramSocket(port, ip);
byte[] sendData = new byte[1024];
sendData = "Hola".getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ip, port);
socket.send(sendPacket);
socket.close();
} catch (Exception e) {
}
}
And here it is the C# server
static UdpClient client;
static IPEndPoint sender;
void Start () {
byte[] data = new byte[1024];
string ip = "127.0.0.1";
int port = 10000;
client = new UdpClient(ip, port);
sender = new IPEndPoint(IPAddress.Parse(ip), port);
client.BeginReceive (new AsyncCallback(recibir), sender);
}
static void recibir(IAsyncResult res){
byte[] bResp = client.EndReceive(res, ref sender);
//Convert the data to a string
string mes = Encoding.UTF8.GetString(bResp);
//Display the string
Debug.Log(mes);
}
The c# server is a Unity file, I mean, I execute it from Unity, so Start is the first method called.
I would like them to communicate through port 10000 (or any ohter one) in my computer, java's main and c#'s start seem to be executed but the callback is never called.
Any ideas of why it isn't working? Thank you all.

BeginReceive() is non-blocking. Your program terminates before it can receive anything. Either use Receive() or put a busy-waiting-loop at the end of the server code.

I've solved it, in the Java client new DatagramSocket() must be called without any argument, and in the c# server new UdpClient(port); must be called only with the port.

Related

Java UDP Server not working

I've created this SpringBoot app, exploring networking communication with Java, over the User Datagram Protocol. I am running the the application in Eclipse Java EE IDE for Web Developers, Version: Oxygen.1a Release (4.7.1a)
Here the main class:
#Override
public void run(String... args) throws Exception {
socket = new DatagramSocket(UDP_PORT);
byte[] receiveData = new byte[BUFFER_SIZE];
byte[] sendData = new byte[BUFFER_SIZE];
LOG.info("UDP server init...");
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String sentence = new String( receivePacket.getData(), 0, receivePacket.getLength() );
LOG.info("recived [" + sentence + "] from " + receivePacket.getAddress());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
DatagramPacket sendPacket = new DatagramPacket(receiveData, receiveData.length, IPAddress, receivePacket.getPort());
socket.send (sendPacket);
}
}
Here a client UDP class I've created to test the Server
public class UDPClient {
private final static int TCP_PORT = 5202;
private DatagramSocket socket;
private InetAddress address;
private byte[] buf;
public UDPClient() throws SocketException, UnknownHostException {
socket = new DatagramSocket();
address = InetAddress.getByName("localhost");
}
public String sendEcho(String msg) throws IOException {
buf = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, TCP_PORT);
socket.send(packet);
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
return received;
}
public void close() {
socket.close();
}
public static void main(String[] args) throws IOException, InterruptedException {
UDPClient udpClient = new UDPClient();
for (;;) {
TimeUnit.SECONDS.sleep(3);
System.out.println
(udpClient.sendEcho("cullons"));
}
}
}
in my computer is working fine, then I deploy the UDPServer on a server, I got the ip using ipconfig
IPv4 Address. . . . . . . . . . . : 214.146.86.201
Then I replace "localhost" for "214.146.86.201", but I don't receive any message in the server.
I've done nc -vzu 214.146.86.201 5202 from my computer
with the result:
MacBook-Pro-de-lopes:$ nc -vzu 214.146.86.201 5202
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif (null)
src 192.166.26.140 port 56827
dst 214.146.86.201 port 5202
rank info not available
Connection to 214.146.86.201 port 5202 [udp/*] succeeded!
But the server prints null on LOG.info("socket InetAddres: " + socket.getInetAddress()); and LOG.info("socket RemoteSocketAddress: " + socket.getRemoteSocketAddress());
I also tried in the server socket = new DatagramSocket(UDP_PORT, InetAddress.getByName("214.146.86.201")); with the same result
The most probable problem could be that the 5202 port on your server is not accessible from the client. The port and their accessibility may not be the same as TCP but anyway there is always the possibility that someone in between is dropping your data packets.
The simplest workaround is to try to run both your client and server code on the server (214.146.86.201). If it can connect means there is definitely a communication issue which (seems) you can check using Netcat as described here. I didn't try it myself.

Java-Client PHP-Server UDP Hole Punching example code

I'm working on a project that will require ea p2p server, but I haven't found any java-client php-server example code. I understand the concept of how udp hole punching works but I can't get anything to work in code.
What I've tried:
TheSocket.java
public class TheSocket {
public static String response = "hello";
public static String request;
public static String webServerAddress;
public static ServerSocket s;
protected static ServerSocket getServerSocket(int port)throws Exception{
return new ServerSocket(port);
}
public static void handleRequest(Socket s){
BufferedReader is;
PrintWriter os;
try{
webServerAddress = s.getInetAddress().toString();
is = new BufferedReader(new InputStreamReader(s.getInputStream()));
request = is.readLine();
System.out.println(request);
os = new PrintWriter(s.getOutputStream(), true);
os.println("HTTP/1.0 200");
os.println("Content-type: text/html");
os.println("Server-name: TheSocket");
os.println("Content-length: " + response.length());
os.println("");
os.println(response);
os.flush();
os.close();
s.close();
}catch(Exception e){
System.out.println("Failed to send response to client: " + e.getMessage());
}finally{
if(s != null){
try{
s.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
return;
}
}
Main.java
public class Main {
public static void main(String[] args)throws Exception{
TheSocket.s = TheSocket.getServerSocket(6789);
while(true){
Socket serverSocket = TheSocket.s.accept();
TheSocket.handleRequest(serverSocket);
}
}
PHP-CONNECT.php - to get the other users port, I manually connect and use the port shown on webpage.
<?php
echo $_SERVER['REMOTE_ADDR'].':'.$_SERVER['REMOTE_PORT'];
?>
The issue with the code above, is that it cant make it to the socket unless I port forward.
Comment if you have any questions!
I was facing a similar problem. And was trying to solve it in a similar way.
Some parts of your code look wrong to me.
Sockets in Java are made for TCP but the title says UDP. Therefore u should use DatagramSockets.
But then we come to the point where i stuck too. HTTP-Requests use tcp as well, so opening the port with HTTP might lead to a corrupt port, after tcp session was closed. (Just a guess)
public class Main {
public static void main(String[] args) {
try
{
String httpRequest = "GET /index.php HTTP/1.1\n" +
"Host: <PHP SERVER NAME HERE>";
InetAddress IPAddress = InetAddress.getByName(<PHP SERVER IP HERE>);
DatagramSocket clientSocket = new DatagramSocket();
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = httpRequest;
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 80);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}catch(Exception e){e.printStackTrace();}
}
}
The Code above theoretically sents a HTTP over UDP request. So that the displayed Port will be the UDP one. In my case i didnt get any response from the PHP Server and stuck at clientSocket.recieve(..) . I guess because the firewall of my webserver is blocking udp packets.
If the code works by anyone i would proceed like this:
save all accessing ips and ports to a DB and list them to the other client.
Write ur Data in DatagramPackets like above to the other client.
I hope this may help. If anyone can get it completly working i would also be interested in it :)

Android UDP doesn't receive in some devices

I have an UDP send and receive which works in my device Samsung Galaxy Ace Plus (S7500) but the same code doesn't work in other devices, for example Samsung Galaxy S4. I don't have any error.
Send :
public class SendThread extends Thread {
byte[] receiveData = new byte[1024];
DatagramSocket serverSocket = null;
public SendThread() {
this.start();
}
public void run() {
DatagramSocket serverSocket = null;
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
try {
serverSocket = new DatagramSocket("MY SOCKET PORT");
InetAddress IP = InetAddress.getByName("MY IP");
String send= "I am Android";
sendData = send.getBytes();
DatagramPacket send = new DatagramPacket(sendData, sendData.length, IP, "MY SEND PORT");
serverSocket.send(send);
serverSocket.close();
} catch (Exception e) {
}
}
}
Receive :
public class ReceiveThread extends Thread {
byte[] receiveData = new byte[1024];
DatagramSocket serverSocket = null;
boolean isActive = true;
public ReceiveThread() {
this.start();
}
public void run() {
DatagramSocket serverSocket = null;
byte[] receiveData = new byte[1024];
while (isActive) {
try {
serverSocket = new DatagramSocket("MY RECEIVE PORT");
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
serverSocket.close();
} catch (Exception e){
}
}
}
}
This problem ocurred because some devices lock the Datagram receiver because the protocol security implemented by factory.
Your code is not wrong, but you need change the DatagramSocket for MulticastSocket.
For this your need execute some steps:
First, it's needed to add the uses-permission:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
On AmdroidManifest.xml
Second, it's necessary create a MulticastLock; Without this the MulticastSocket is not work properly;
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
Thirdy, replace the DatagramSocket by MulticastSocket. Only on receive methods was needed put the code below or similar:
MulticastSocket ms = new MulticastScoket("Your socket port");
ms.joinGroup("Your IP");
It's not needed any modifies to send messages.
I use the multcast ip equals to 239.255.255.255. Attempt to range of multicast ip because the wrong ip will block the method flow correctly.
Finally, before use MulticastSocket it's needed to execute MulticastLock.acquire(), and after use execute MulticastLock.release();
It could be puted on service, and acquire or release MulticastLock on start or stop service.

Send packet from a network adapter to another network adapter on the same computer

Basically what I want to do is simulate an application with 4 clients and 1 server, but I only have one computer to do so.
I created two loopback adapter 169.254.153.173 (server) and 169.254.168.136 (client) to test.
public class Server {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9001, InetAddress.getByName("169.254.153.173"));
System.out.println(socket.getLocalAddress().getHostAddress());
System.out.println();
byte[] buf = new byte[1];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println(packet.getAddress());
System.out.println(packet.getPort());
System.out.println(buf[0]);
System.out.println();
socket.close();
}
}
public class Client {
public static void main(String[]args) throws Exception {
DatagramSocket socket = new DatagramSocket(9000, InetAddress.getByName("169.254.168.136"));
System.out.println(socket.getLocalAddress().getHostAddress());
byte[] buf = {42};
DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("169.254.153.173"), 9001);
socket.send(packet);
socket.close();
}
}
Unfortunately, even tho the code looks fine, my server never receives the packet. I know it works using localhost but that's not what I want since I want to bind the ip to the socket as if it was on another computer.

Send and Receive from a single DatagramSocket in Java

Is it possible to use a single DatagramSocket to send and receive packets in a single Java application? I have been attempting to do this using threads but have had not luck. Every socket tutorial I find online uses separate client and server classes to send data. However, in my case, I want the client and server to reside in a single application. Below is my attempt:
public class Main implements Runnable {
// global variables
static DatagramSocket sock;
String globalAddress = "148.61.112.104";
int portNumber = 9876;
byte[] receiveData = new byte[1024];
public static void main(String[] args) throws IOException {
sock = new DatagramSocket();
(new Thread(new Main())).start();
// send data
while (true) {
InetAddress IPAddress = InetAddress.getByName("127.0.0.1");
int port = 9876;
int length = 1024;
byte [] sendData = new byte[1024];
String message = "hello";
sendData = message.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
IPAddress, port);
sock.send(sendPacket);
}
}
public void run() {
//get incoming data
while (true) {
byte[] sendData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
receivePacket.setPort(portNumber);
try {
sock.receive(receivePacket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String sentence = new String(receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
}
}
}
As you can see I am sending data in a loop on the main thread and receiving data on the loop in the runnable thread. The main thread should continuously send "hello" to the receiver and output the message. However, no output is given?
Am I on the right track here? Is using threads the best way to do this? Is this even possible? And if so is there a better solution?

Categories