Java(Android): create ServerSocket on LocalPort used for another Socket - java

I'm a little stumped and probably because I don't know how to search for this properly (I've tried many different keywords). Anyway, I'm attempting a variation of TCP hole punching(with a rendezvous server). I have created a TCP socket to the server and closed it without throwing any exceptions. But when I attempt to create a ServerSocket on the localport of the original socket it fails with IOException.
private static int LOCALPORT = 0;
private static String TARGETIP = "88.888.88.888";
private static int TARGETPORT = 8888;
try{
InetAddress serverAddr = InetAddress.getByName(TARGETIP);
socket = new Socket(serverAddr, TARGETPORT);
LOCALPORT = socket.getLocalPort();
socket.close();
ServerSocket sSocket = new ServerSocket(LOCALPORT);
Socket skt = sSocket.accept();
}
catch (IOException e){
}
I just cannot wrap my head around why I cannot close the socket and open a serversocket on the same port.
UPDATE: from logcat
java.net.BindException: bind failed: EADDRINUSE (Address already in use)
Caused by: libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)

I think your socket = new Socket(serverAddr, TARGETPORT); throws the IOException. Because the IP Address you are using is invalid. Otherwise this code should work fine.

You will get an IOException trying to listen on the just retrieved local port:
bind failed: EADDRINUSE (Address already in use)
That should be in my opinion:
port already in use
Why that port is not released i don't know. Would there be a possibility to unbind it?

I believe I have solved my own problem thanks to greenapps and some additional searching online. Instead of closing the original socket, you need to set it to reuse instead! So simple, wow.
private static int LOCALPORT = 0;
private static String TARGETIP = "88.888.88.888";
private static int TARGETPORT = 8888;
try{
InetAddress serverAddr = InetAddress.getByName(TARGETIP);
socket = new Socket(serverAddr, TARGETPORT);
LOCALPORT = socket.getLocalPort();
//socket.close();
socket.setReuseAddress(true);
ServerSocket sSocket = new ServerSocket(LOCALPORT);
Socket skt = sSocket.accept();
sSocket.close();
}
catch (IOException e){
e.getMessage();
e.printStackTrace();
}

Related

UDP communication between Java and C#

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.

Cannot communicate with server in Java

I am trying to write server to client program but I cannot communicate with the server in Java.
Here is the code block in my main.
InetAddress addr = InetAddress.getLocalHost();
ipAddress = "78.162.206.164";
ServerSocket serverSocket = new ServerSocket(0);
String randomStringForPlayerName = RandomStringGenerator.generateRandomString();
baseForReqOpp += ipAddress + " " + serverSocket + " " + randomStringForPlayerName;
Socket socket = new Socket(host,2050);
socket.setSoTimeout(100);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
out.write(baseForReqOpp);
out.flush();
System.out.println(in.read());
I know that there is no problem in the server code and all the communication ports are ok.
But I cannot read anything from the server.
What can be the problem?
you have to create an output stream before the input stream
Here is some working code with communicating client and server sockets. Hopefully you can adapt it for your specific problem.
public class SocketTest {
public void runTest() {
try {
// create the server
new SimpleServer().start();
// connect and send a message
InetAddress addr = InetAddress.getLocalHost();
Socket sock = new Socket(addr, 9090);
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject("Hello server");
out.flush();
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
System.out.println("from server: " + in.readObject());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// server has to run in a separate thread so the code doesn't block
private class SimpleServer extends Thread {
#Override
public void run() {
try {
ServerSocket sock = new ServerSocket(9090);
Socket conn = sock.accept();
// the code blocks here until a client connects to the server
ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
System.out.println("from client: " + in.readObject());
ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream());
out.writeObject("Hello client");
out.flush();
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
To run it:
new SocketTest().runTest();
Your code will never work because you don't use threads. In order to start the server, you need to call accept at some point in your code
myServerSocket.accept();
this is a blocking call, ie the code flow stops until a client connects. But since you can't execute any statement (remember accept is blocking?) how can a client connect? This chicken and egg problem is resolved through threads. See Howard's answer for a code sample.
I don't see any call to accept(), so I wonder what your client connects to...

Cannot receive data by a socket from a device (in WLAN) via UDP

my android device is connected to my home-wireless-network. Also a special UDP-device is connected to it. My android app successfully can send commands to the UDP-device. But if I open a socket it does not receive data. Can you see what is wrong? I know the ip of the UDP-device from the iphone-APP which is working
Here is how the app send commands:
public static final String SERVERIP = "192.168.2.114";
public static final int PORT = 44444;
public void run() {
try {
serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket();
byte[] buf = message.toByteArray();
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, PORT);
socket.send(packet);
socket.close();
} catch (Exception e) {
Log.e("UDP", "Sender/Client: Error", e);
}
}
Whereas I have two approaches for receiving data:
public static final String SERVERIP = "192.168.2.114";
public static final int SERVERPORT = 44445;
private InetAddress serverAddr;
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddr);
byte[] buf = new byte[65213];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
} catch (Exception e) {
Log.e("UDP", "Receiver: Error", e);
}
try {
serverAddr = InetAddress.getByName(SERVERIP);
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
byte[] buf = new byte[65213];
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, SERVERPORT);
socket.receive(packet);
socket.close();
} catch (Exception e) {
Log.e("UDP", "Sender/Client: Error", e);
}
}
The approach in the first try block leads to an exception:
java.net.BindException: Cannot assign requested address
at org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
at dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:268)
at org.apache.harmony.luni.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:81)
at java.net.DatagramSocket.createSocket(DatagramSocket.java:193)
at java.net.DatagramSocket.<init>(DatagramSocket.java:95)
at de.myappname.connection.Receiver.run(Receiver.java:29)
at java.lang.Thread.run(Thread.java:1019)
The second approach just blocks the thread by socket.receive(packet) which does not receive data. From the iphone and specification I know the device sends data via UDP 44445 over WLAN. Any suggestions what is wrong?
Thank you!
UDP port 44445 is used by eMule protocol. Do you have any other eMule clients active on your device?
Update:
The problem seems to be the address you bind to - it must be an address on the localhost, i.e. IP address of your device, not remote device. See DatagramSocket(port, InetAddress) constructor.
I guess you need to put the receive() function inside a while loop since you current code looks like it receives message only once; it doesn't guarantee that it will contain any valid data.

How to write data to Socket opened by Flex from Java Server

Ok, basically my Flex app will open up a socket and listen on it. My java program will write some string to this port.
My AS3 code is
private function onRecvClick():void
{
var host:String = "localhost";
var port:int = 9090;
var socket:Socket = new Socket(host, port);
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(DataEvent.DATA, onData);
socket.connect(host, port);
}
And my Java code is :
private ClientSocket()
{
try
{
String host = "localhost";
int port = 9090;
Socket socket = openSocket(host, port);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("HelloTest");
writer.flush();
}
catch (Exception e)
{
System.out.println(e);
}
}
private Socket openSocket(String server, int port) throws Exception
{
Socket socket;
// create a socket with a timeout
try
{
InetAddress inteAddress = InetAddress.getByName(server);
SocketAddress socketAddress = new InetSocketAddress(inteAddress, port);
// create a socket
socket = new Socket();
// this method will block no more than timeout ms.
int timeoutInMs = 10*1000; // 10 seconds
socket.connect(socketAddress, timeoutInMs);
return socket;
}
catch (SocketTimeoutException ste)
{
System.err.println("Timed out waiting for the socket.");
ste.printStackTrace();
throw ste;
}
}
While trying to write to the socket, i am getting this java.net.ConnectException: Connection refused: connect. Funny thing is that the socket in Flex doesn't seem to dispatch any events, is it normal for that to happen?
Unless I'm misreading the docs completely, both flash.net.Socket and java.net.Socket are client sockets.
You need one side to be a server socket to be able to connect them together.
For the server side in Java, look at this walkthrough: Socket Communications.

Socket not closing serverside when calling socket.close() in client JAVA

I'm having problems with sockets in java. I have a ServerSocket that is listening with accept() and spawns threads for each client-request. Communication between clients and the server works fine. I am using an inputstream to read data from clients in the serverthreads, like:
inputStream = mySocket.getInputStream();
bytes = inputStream.read(buffer);
My problem is that if I call socket.close() from the clients, nothing happens to the blocking call of bytes = inputStream.read(buffer);, it continues to block. But it works if I close the socket from the server, then the inputStream.read(buffer); of the client returns "-1".
SERVER-MAINTHREAD:
//SERVER MAIN THREAD, SPAWNS CLIENT THREADS
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (listening){
new ServerThread(serverSocket.accept(), monitor).start();
}
SERVER-CLIENTTHREADS:
public class ServerThread extends Thread{
public ServerThread(Socket socket, Monitor monitor) {
this.socket = socket;
this.monitor = monitor;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes;
//Listen
while(true){
try {
InputStream inputStream = socket.getInputStream();
monitor.doStuffWithOtherThreads(Object myObject);
bytes = inputStream.read(buffer); //Problem
if (bytes == -1){
System.out.println("breaks");
break;
}
byte[] readBuf = (byte[]) buffer;
String readMessage = new String(readBuf, 0, bytes);
System.out.println(readMessage);
System.out.println(bytes);
} catch (IOException e) {
System.out.println("Connection closed");
break;
}
}
}
CLIENT:
InetAddress serverAddr = InetAddress.getByName("serverhostname");
socket = new Socket(serverAddr, PORT);
socket.close(); //Close the socket connection from client. Nothing happens in the serverthread
The server code you posted doesn't check for -1. So either that is the problem or that isn't the real code, in which case you should post the real code for comment.
EDIT The code you have posted does not behave as you have described.
Try this in your Android client code :
socket.shutdownOutput();
socket.close();
It should be better ;-)
I don't know if I understand your issue, but I would say that it is normal that it's up to the server to close the socket.
On server side (in an independent thread) you have the listening socket :
ServerSocket socketServeur = new ServerSocket(port);
Then probably (in the same thread if it is a small server) a loop accepting incoming connections (no exception management, probably the socket.close is in a finally block) :
while (! askedToClose) {
Socket socket = socketServeur.accept();
doSomethingWithRequest(socket);
socket.close();
}
On the client side, you have :
Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(port));
OutputStream output = clientSocket.getOutputStream();
// send something to server
InputStream input = clientSocket.getInputStream(); // will block until data is available
// reading response
The server should know when it has reached the end of the request. For example in http it could be (taken from a mockHttpServer in scala so there might be some errors but the process is the same):
void doSomethingWithRequest(Socket socket) {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream));
StreamWriter outputWriter = new OutputStreamWriter(socket.getOutputStream);
StringBuilder requestBuilder = new StringBuilder();
do {
requestBuilder.append(inputReader.read().toChar());
} while (!requestBuilder.toString().endsWith("\r\n\r\n"));
saveUri(getUriFromRequest(requestBuilder.toString()));
outputWriter.write("HTTP/1.1 200 OK\r\n\r\n");
outputWriter.flush();
inputReader.close();
outputWriter.close();
}
EDIT :
I read the code added and I still don't get it :
you call Socket.close(), but this method is not static
you loop forever in the "server"
I have the impression that you use the same socket for client and server
You have 3 "sockets" :
the listening socket (object ServerSocket)
the accept socket (Object Socket sent by socketServer.accept())
the client socket (like above in the example)
The server open and close listening and "accept" socket, and should have no impact of bad client socket management.
Then if you want your server to accept several concurrent connections, you may add a ThreadPool for accepting connections and treating requests and responses.

Categories