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.
Related
I have a program wHich puts the inetAddress and port for each client connected to the UDP server in a hashmap. The reason for this is so i can take messages from clients send them to the server and send them over to some other clients inside the hashmap.
However when i do this it only puts it only once inside the hashmap. How could i make it so for every new client it would add a HashMap<InetAdress, Integer> for every new client connection?
server:
private static int port = 9001;
private static HashMap<InetAddress, Integer> clients = new HashMap<InetAddress, Integer>();
public static void main(String[] args) throws Exception {
DatagramSocket UDPSocket = new DatagramSocket(9002);
System.out.println("[SERVER] UDP Server successfully launched on port: " + port);
byte[] data = new byte[1000];
DatagramPacket receivePacket = new DatagramPacket(data, data.length);
while (true) {
UDPSocket.receive(receivePacket);
while(true) {
InetAddress ip = receivePacket.getAddress();
int port = receivePacket.getPort();
clients.put(ip, port);
}
}
}
client:
public ChatClient() throws UnknownHostException, IOException {
Scanner scanner = new Scanner(System.in);
DatagramSocket UDPSocket = new DatagramSocket();
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
InetAddress ip = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, ip, 9002);
UDPSocket.send(packet);
}
}
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 :)
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.
I have a problem to run a server and clients in one (mac) machine. I can run the server but when I run the client it give me an error java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
as far as I know that there is somthing call ssh that need to be used but I don't know how to use it to do solve this.
Thanks
public class WRRCourseWork {
public static void main(String[] args) {
try {
DatagramSocket IN_socket = new DatagramSocket(3000);
DatagramSocket OUT_socket = new DatagramSocket(5000);
IN_socket.setSoTimeout(0);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
//recive the message
IN_socket.receive(packet);
String message = new String(buffer);
System.out.println("Got message: " + message.trim());
// send the message
String host = "";
InetAddress addr = InetAddress.getByName(host);
DatagramPacket OUT_Packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 5000);
OUT_socket.send(OUT_Packet);
System.out.println("Sending Message: "+ message.trim());
}
} catch (Exception error) {
error.printStackTrace();
}
}
... client
public class Messages {
public static void main(String [] args) {
System.out.println("hiiiiiii");
//String host = "localhost";
try {
while (true) {
InetAddress addr = InetAddress.getLocalHost();
String message = "Hello World";
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 4000);
DatagramSocket socket = new DatagramSocket(4000);
socket.send(packet);
//socket.close();
}
} catch(Exception error) {
// catch all errors
error.printStackTrace();
}
}
}
Your server is listening on port 3000 so change your client to also use port 3000 and to only specify port 3000 once, in the packet definition not in the socket.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Messages {
public static void main(String [] args) {
System.out.println("hiiiiiii");
//String host = "localhost";
DatagramSocket socket = null;
try {
while (true) {
InetAddress addr = InetAddress.getLocalHost();
String message = "Hello World";
DatagramPacket packet =
new DatagramPacket(message.getBytes(),
message.getBytes().length, addr, 3000);
socket = new DatagramSocket();
socket.send(packet);
socket.close();
}
} catch(Exception error) {
// catch all errors
error.printStackTrace();
}
}
}
The results on the server should then be:
Got message: Hello World
Sending Message: Hello World
Got message: Hello World
Sending Message: Hello World
Got message: Hello World
Sending Message: Hello World
. . .
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.