I am new to working with sockets, and I am working on this project where a connection between my android flutter app and a java server is needed, to do this I am trying socket programming.
The server code is fairly simple, I create a new thread for every client connected and I give them a bunch of URLs, later on, this should be replaced by a query result. here is the java code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CrawlitServer {
// The port number on which the server will listen for incoming connections.
public static final int PORT = 6666;
//main method
public static void main(String[] args) {
System.out.println("The server started .. ");
// Create a new server socket
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
// Listen for incoming connections and create a new thread for each one
while (true) {
try {
new CrawlitServerThread(serverSocket.accept()).start();
}
catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
public static class CrawlitServerThread extends Thread {
private final Socket socket;
public CrawlitServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
List<String> list = new ArrayList<>();
//assign a value to list
list.add("http://www.google.com");
list.add("http://www.yahoo.com");
list.add("http://www.bing.com");
list.add("http://www.facebook.com");
list.add("http://www.twitter.com");
list.add("http://www.linkedin.com");
list.add("http://www.youtube.com");
list.add("http://www.wikipedia.com");
list.add("http://www.amazon.com");
list.add("http://www.ebay.com");
list.add("http://stackoverflow.com");
list.add("http://github.com");
list.add("http://quora.com");
list.add("http://reddit.com");
list.add("http://wikipedia.org");
try {
// Get the input stream from the socket
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
Scanner scanner = new Scanner(inputStream);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
PrintWriter writer = new PrintWriter(outputStream, true);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println("Received Message from client: " + line);
writer.println(list + "\n");
}
}
catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
}
Now I run this server and connect to it using sockets in Flutter, I give it the IP address I get from the ipconfig command, and here is the dart code:
import 'dart:async';
import 'dart:io';
//Utilities that manage connections with server sockets.
//ServerUtil Class
class ServerUtil {
static const port = 6666;
static const host = MY_IP_GOES_HERE;
static late Socket socket;
static bool connected = false;
//a list of urls returned by the server
static List<String> urls = [];
//Constructor
ServerUtil() {
//Initialize the socket.
Socket.connect(host, port).then((Socket sock) {
socket = sock;
connected = true;
socket.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
//send a message to the server.
}).catchError((e) {
print("Unable to connect: $e");
});
}
//Query method that sends a message to the server. The server will return a list of urls.
//The urls will be added to the urls list.
//The urls list will be returned.
static Future<List<String>> query(String userQuery) async {
urls.clear();
//check if socket is connected.
if (connected) {
//send the query to the server.
socket.writeln(userQuery);
await Future.delayed(const Duration(milliseconds: 200));
print(urls);
return urls;
}
//if socket is not connected, wait for 5 seconds and try again.
await Future.delayed(const Duration(milliseconds: 50));
return query(userQuery);
}
//Handles data from the server.
void dataHandler(data) {
//String of received data.
String dataString = String.fromCharCodes(data).trim();
//remove first and last character from the string.
dataString = dataString.substring(1, dataString.length - 1);
//remove all the whitespace characters from the string.
dataString = dataString.replaceAll(RegExp(r'\s+'), '');
urls = dataString.split(',');
}
//Handles errors from the server.
void errorHandler(error, StackTrace trace) {
print(error);
}
//Handles when the connection is done.
void doneHandler() {
socket.destroy();
}
}
This works perfectly fine while using a debug apk running it on my real Note 9 device. The problem however is that when I build a release apk and try it out, nothing happens.
The way I set it up is that I wait for the query method in an async and then I send the result to a new screen and push that screen into the navigator.
But in the release apk nothing happens, the new screen doesn't load.
So this leads me to my first question:
Is there a way to debug a release apk? see what exceptions it throws or print some stuff to console?
I have the server running on my Laptop, and the app runs on my phone which is on the same WIFI network.
My second question is:
Do I need to enable some sort of option with my router or my laptop to allow my phone to connect? it does connect in debug mode without any modifications
I tried some random things, like using 'localhost' instead of my IP, as I would normally connect say with a java client for example, but it didn't work.
My last question is:
Does the release apk or like android OS prevent connections to local hosts, maybe because it thinks it is not secure? but then it still connects in debug mode.
Thank you for your time.
Related
I am trying to create a chat application which has one publisher, one server and multiple subscribers. The publisher(Sending to port 8000) sends a message to the server(listening on port 8000 and 5000) and which forwards it further to the subscriber(listening on port 5000).
Now so far I can create multiple publishers and the communication between server and publisher is working, however, I am not able to send it to the subscriber the message sent by the publisher
Server Side Code
package serverclient;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server extends Thread{
private Socket socket;
private int clientNumber;
public Server(Socket socket, int clientNumber){
this.socket = socket;
this.clientNumber = clientNumber;
if(socket.getLocalPort() == 5000)System.out.print("\nSubscriber "+ clientNumber +" is connected to the server");
if(socket.getLocalPort() == 8000)System.out.print("\nPublisher "+ clientNumber +" is connected to the server");
}
#Override
public void run(){
try {
BufferedReader dStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(true){
synchronized(this){
String clMessage = dStream.readLine();
System.out.println("\n"+clMessage);
// if(socket.getLocalPort() == 5000){
out.println("Hey the server is sending the message to subscriber");
// }
//out.println("Hey the publisher has sent the message : " + clMessage);
}
}
} catch (IOException ex) {
System.out.print("\nError has been handled 1\n");
}finally{
try {
socket.close();
} catch (IOException ex) {
System.out.print("\nError has been handled 2\n");
}
}
}
public static void main(String [] args) throws IOException{
int subNumber = 0;
int pubNumber = 0;
ServerSocket servSockpub = new ServerSocket(8000);
ServerSocket servSocksub = new ServerSocket(5000);
try {
while (true) {
Server servpub = new Server(servSockpub.accept(),++pubNumber);
servpub.start();
System.out.print("\nThe server is running on listen port "+ servSockpub.getLocalPort());
Server servsub = new Server(servSocksub.accept(),++subNumber);
servsub.start();
System.out.print("\nThe server is running on listen port "+ servSocksub.getLocalPort());
}
} finally {
servSockpub.close();
servSocksub.close();
}
}
}
publisher code
package serverclient;
import java.net.*;
import java.io.*;
public class Publisher {
public static void main (String [] args) throws IOException{
Socket sock = new Socket("127.0.0.1",8000);
// reading from keyboard (keyRead object)
BufferedReader keyRead = new BufferedReader(new InputStreamReader(System.in));
// sending to client (pwrite object)
OutputStream ostream = sock.getOutputStream();
PrintWriter pwrite = new PrintWriter(ostream, true);
InputStream istream = sock.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
System.out.println("Start the chitchat, type and press Enter key");
String receiveMessage,sendMessage;
while(true)
{
sendMessage = keyRead.readLine(); // keyboard reading
pwrite.println(sendMessage); // sending to server
pwrite.flush(); // flush the data
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
else{
System.out.print("Null");
}
}
}
}
subscriber
package serverclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class Subscriber {
public static void main (String [] args) throws IOException{
Socket sock = new Socket("127.0.0.1",5000);
// receiving from server ( receiveRead object)
InputStream istream = sock.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
System.out.println("Recive side");
String receiveMessage, sendMessage;
while(true)
{
System.out.print("Hey man " + receiveRead.readLine() + "\n");
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
else{
System.out.print("Null");
}
}
}
}
Any help is appreciated. I just want to figure out why subscriber is not reciveing message
There are many possibilities to handle realm time communication issues. I myself prefer the use of Events / EventListeners.
Currently in your program there is no communication between the Server as such and the threads which handle the subscriber connection.
Also on a side node: even with a proper communication between publisher connection threads and subscriber connection threads it won't work now since you are using the same Server class. This does not only violate the Single-Responsibility-Principle but will also prevent the server from ever sending a message to the Subscriber.
Let's say you have establish a connection and your server class is now connected with the subscriber. What will happen?
The subscriber will loop until there is a message on the input stream of his socket. Good that is exactly what we want. But what does the server do? The truth is exactly the same. The first few statements in the try block of your Server's run method are to create a BufferedReader and read from it until a message receives. And now we have a socket on each site which will infinitly wait for some kind of message to arrive (which will obviously never happen since both are waiting for something).
To prevent this you should check if there is anything to read on the stream first:
while ( true )
{
if ( socket.getInputStream().available() != 0 )
{
// reading logic goes here....
synchronized ( this )
{
String clMessage = dStream.readLine();
System.out.println( "\n" + clMessage );
out.println( "Hey the server is sending the message to subscriber" );
}
}
// what shall be done when not reading.
}
Now the second part. If you want to communicate between threads you need to implement some logic to do so. As stated above I love the concept of Listeners so i will show an example where I make use of them:
MessageReceivedListener.java
import java.util.EventListener;
public interface MessageReceivedListener
extends EventListener
{
public void onMessageReceived( String message );
}
Note: The interface does not have to extend EventListener since EventListener
is just a tagging interface. I myself still prefer to have this as a reminder for what purpose the interface is there.
Server.java (excerpt)
// New constructor since we will pass a Listener now. Also new local variable for it.
public Server( Socket socket, int clientNumber, MessageReceivedListener mrl )
{
this.socket = socket;
this.clientNumber = clientNumber;
this.mrl = mrl;
if ( socket.getLocalPort() == 5000 )
System.out.print( "\nSubscriber " + clientNumber + " is connected to the server" );
if ( socket.getLocalPort() == 8000 )
System.out.print( "\nPublisher " + clientNumber + " is connected to the server" );
}
The new constructor provides a way to pass the MessageReceivedListener to the Server object. Alternatively you can alsocreate a setter for it.
synchronized ( this )
{
String clMessage = dStream.readLine();
System.out.println( "\n" + clMessage );
out.println( "Hey the server is sending the message to subscriber" );
mrl.onMessageReceived( clMessage );
}
This is where the magic happens. After whe receive the message we just pass it to the onMessageReceived(String message) method of the listener. But what does it do exactly? This is what we define when creatinga Server object.
Here are two examples, one with anonymous classes (Java 7 and before) and on with lambdas (Java 8 and later).
Example Java 7 and earlier
Server servpub = new Server( servSockpub.accept(), ++pubNumber,
new MessageReceivedListener()
{
#Override
public void onMessageReceived( String message )
{
// call nother local method
// this method would need to be a static method of Server
// because it's in the scope of your server class
sendMessageToSubscribers(message);
}
} );
Here we pass an anonymous class as our MessageReceivedListener object and define it's behaviour (in this case just calling another method which will handle the rest.
Now since our MessageReceivedListener interface does only contain one method we can also see it as a functional interface and therefore use lambdas to shorten the code and improve readability.
Example with Lambda (Java 8 and later)
Server servpub = new Server( servSockpub.accept(), ++pubNumber, Server::sendMessageToSubscribers);
In this specific case we only have one argument which we want to pass to a method and therefore can use a method reference.
How to actually implement the method sendMessageToSubs(String message) is up to you. But you need to keep track of how many Threads with subscriber connections have been created and how you want to reference them.
My Java application establishes TCP connection with a server and communicates with it every second by sending and receiving messages. Both server and client are run on the same Mac. In about 15-20 minutes, my server crashes with error "Errno::EMFILE Too many files open". Here is my client code:
package testtcp;
import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestTCP extends JPanel
{
JFrame frame = new JFrame("Button Demo");
ScheduledExecutorService executorService;
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream output = null;
private BufferedReader br = null;
private boolean isMapUpdating = false;
public TestTCP()
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300,300));
frame.add(this);
JButton b1 = new JButton("BLACK");
b1.setPreferredSize(new Dimension(150,50));
b1.setFocusPainted(false); // get rid of border around text
add(b1);
b1.addActionListener((java.awt.event.ActionEvent evt) ->
{
startAcarsConnection();
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void startAcarsConnection()
{
start();
}
public void start()
{
System.out.println("THREAD START");
// Default timer rate
int timerRate = 1;
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(new Runnable()
{
#Override
public void run()
{
// Create new TCP connection if the map is not currently updating
if(isMapUpdating == false)
{
isMapUpdating = true;
communicateWithServer();
}
}
}, 0, timerRate, TimeUnit.SECONDS);
}
public void stop()
{
executorService.shutdown();
}
public void communicateWithServer()
{
// Create a message to the server
String messageToServer = makeMessageToServer();
// Connect to the client and receive the response
String messageFromServer = connectToClient(messageToServer);
SwingUtilities.invokeLater(() ->
{
messageReceived(messageFromServer);
});
}
public String connectToClient(String messageToServer)
{
String data = "";
// Message from the server that should terminate TCP connection
String terminator = "END_IGOCONNECT_DATA";
try
{
// Create socket and streams
socket = new Socket("192.168.1.2", 7767);
input = new DataInputStream( socket.getInputStream());
output = new DataOutputStream( socket.getOutputStream());
//Send message to the server
output.writeBytes(messageToServer);
System.out.println("MESSAGE TO SERVER FROM CONNECT TO CLIENT: "+messageToServer);
//Read Response
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String s = "";
int value;
// Process the message from the server and add to the StringBuilder
while((value = br.read()) != -1)
{
// converts int to character
char c = (char)value;
sb.append(c);
if(sb.toString().contains(terminator))
{
break;
}
}
// Create the final string
data = sb.toString();
}
catch (UnknownHostException e)
{
System.out.println("Sock:"+e.getMessage());
// Close Connection
cancelConnection();
// Pop-up message that the airport was not found
String message = "Application was not able to establish connection with X-Plane.\n"
+ "Check whether IP Address and Port number were correctly entered in Settings.\n"
+ "Check whether connection is not being blocked by your firewall.";
JOptionPane.showMessageDialog(new JFrame(), message, "TCP Connection Error: UnknownHostException",
JOptionPane.ERROR_MESSAGE);
data = "ERROR";
}
catch (EOFException e)
{
System.out.println("EOF:"+e.getMessage());
// Close Connection
cancelConnection();
// Pop-up message that the airport was not found
String message = "Application was not able to establish connection with X-Plane.\n"
+ "Check whether IP Address and Port number were correctly entered in Settings.\n"
+ "Check whether connection is not being blocked by your firewall.";
JOptionPane.showMessageDialog(new JFrame(), message, "TCP Connection Error: EOFException",
JOptionPane.ERROR_MESSAGE);
data = "ERROR";
}
catch (IOException e)
{
System.out.println("IO:"+e.getMessage());
// Close Connection
cancelConnection();
// Pop-up message that the server was not found
if(!e.getMessage().equals("Socket closed"))
{
String message = "Application was not able to establish connection with X-Plane.\n"
+ "Check whether IP Address and Port number were correctly entered in Settings.\n"
+ "Check whether connection is not being blocked by your firewall.";
JOptionPane.showMessageDialog(new JFrame(), message, "TCP Connection Error: IOException",
JOptionPane.ERROR_MESSAGE);
}
// "Connection reset"
data = "ERROR";
}
finally
{
// TO DO!!! DISABLED FOR NOW!! closeSocketPax();
}
return data;
}
public void cancelConnection()
{
executorService.shutdown();
closeSocketPax();
SwingUtilities.invokeLater(() ->
{
System.out.println("Cancel Connection");
});
}
private void closeSocketPax()
{
try
{
if(socket!=null) { socket.close();}
if(input != null) { input.close();}
if(output != null) { output.close();}
if(br != null) { br.close();}
}
catch (IOException ex)
{
String message = "Error closing socket.";
JOptionPane.showMessageDialog(new JFrame(), message, "TCP Connection Error: IOException",
JOptionPane.ERROR_MESSAGE);
}
socket = null;
input = null;
output = null;
br = null;
}
private String makeMessageToServer()
{
return "MESSAGE TO SERVER";
}
private void messageReceived(String message)
{
System.out.println("MESSAGE RECEIVED: "+message);
isMapUpdating = false;
}
public static void main(String[] args)
{
new TestTCP();
}
}
I have been trying to solve this for almost a month already!
Does anyone see a problem in the code and know how to mitigate the problem? Greatly appreciated!
Each connection you create uses a file descriptor. In any operating system there is a limit to the number of descriptors your process can have. For example, in the Linux environment I'm on the limit is 1024. Different O/S's have different limits but in Unix derived environments like Linux and Mac O/S you can run ulimit -n to see what the limit is.
In your code you do:
socket = new Socket("192.168.1.2", 7767);
in the connectToClient method. Each time you do that and you don't close the socket you use up a file descriptor. Eventually you reach the O/S defined limit and you get, in Mac O/S the Errno::EMFILE error.
You have two choices to fix this. The first is pretty much what you have commented out - close the connection when you're done with it. However, as you indicate in the comments this is occurring very frequently and you don't want to incur the overhead of opening and closing constantly.
That brings us to the second choice - reuse the connection. A socket can send data over and over again if the protocol you're designing handles it. Send the data back and forth over the protocol and reuse the Socket.
A warning though - if your physical connection is somehow severed - for example, you switch from Ethernet to Wi-Fi - your service will still need to deal with possible errors. Your code has most of that but you may want to consider closing and attempting to reconnect when this occurs.
I have a simple pair of client and server programs. Client connects to server and when it does connect, the server replies with a "Hello there" message. How should I modify the program if I want the client and server programs to run on different systems?
Here is the code for the client side..
package practice;
import java.io.*;
import java.net.*;
public class DailyAdviceClient
{
public static void main(String args[])
{
DailyAdviceClient dac = new DailyAdviceClient();
dac.go();
}
public void go()
{
try
{
Socket incoming = new Socket("127.0.0.1",4242);
InputStreamReader stream = new InputStreamReader(incoming.getInputStream());
BufferedReader reader = new BufferedReader(stream);
String advice = reader.readLine();
reader.close();
System.out.println("Today's advice is "+advice);
}
catch(Exception e)
{
System.out.println("Client Side Error");
}
}
}
and here is the code for the server
package practice;
import java.io.*;
import java.net.*;
public class DailyAdviceServer
{
public static void main(String args[])
{
DailyAdviceServer das = new DailyAdviceServer();
das.go();
}
public void go()
{
try
{
ServerSocket serversock = new ServerSocket(4242);
while(true)
{
Socket outgoing = serversock.accept();
PrintWriter writer = new PrintWriter(outgoing.getOutputStream());
writer.println("Hello there");
writer.close();
}
}
catch(Exception e)
{
System.out.println("Server Side Problem");
}
}
}
just change "127.0.0.1" on the client with the server's IP and make sure the port 4242 is open.
Socket incoming = new Socket("127.0.0.1",4242);
This is creating a socket listening to the server at the address 127.0.0.1 on port 4242. If you change the server to another address, for example of a different pc, then change the ip address that your socket is listening to.
It is also worth noting that you will probably have to open up or allow access to the ports you are using.
Client requires ip address and port of server, means ip of that system which you making server and port (4242).so in client you need to change
Socket incoming = new Socket("127.0.0.1",4242); BY
Socket incoming = new Socket("IP address of server",4242);
And make sure both system is connected via wired or wireless network.
I'm trying to build a chat program. I wrote the code and everything worked and still works great when I'm using my computer and connecting using 127.0.0.1. I also succeeded to connect successfully between my laptop and my computer, which run on the same router. (I used an internal IP address to do this, 10.0.0.3).
Now I'm trying to make a connection between my router and other routers. And to this I'm trying to connect to an external IP address. I do the port forwarding part through my router and I also made a static IP. When I run the code I always get a "connection refused error".
Here is the code:
MainServer.java:
import java.util.*;
import java.io.*;
import java.net.*;
public class MainServer {
private ArrayList<Socket> sockets;
public MainServer() {
ServerSocket server_socket;
try {
server_socket = new ServerSocket(5005);
sockets = new ArrayList<Socket>();
System.out.println("server is now running");
while(true) {
Socket socket = server_socket.accept();
sockets.add(socket);
try {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println("---you are connected to the server---\r\n");
writer.flush();
} catch(Exception e) {e.printStackTrace();}
System.out.println("server connected to " + socket.getInetAddress());
Reader reader = new Reader(socket);
Thread thread = new Thread(reader);
thread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
MainServer server = new MainServer();
}
class Reader implements Runnable {
Socket socket;
public Reader(Socket socket) {
this.socket=socket;
}
public void run() {
while(true) {
try {
InputStreamReader stream_reader = new InputStreamReader(socket.getInputStream());
BufferedReader reader = new BufferedReader(stream_reader);
while(true) {
String str = reader.readLine();
if(str==null)
continue;
System.out.println("message from the client " + socket.getInetAddress() + ": " + str);
send_back_message(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void send_back_message(String str) {
try {
for(Socket send_to_socket: sockets) {
PrintWriter writer = new PrintWriter(send_to_socket.getOutputStream());
writer.println(send_to_socket.getInetAddress()+ ": " + str);
writer.flush();
}
} catch(Exception e) {e.printStackTrace();}
}
}
}
Client.java:
public Client() {
frame = new JFrame();
JPanel panel = new JPanel();
chat = new JTextArea(20,40);
chat.setEditable(false);
JScrollPane scroll = new JScrollPane(chat);
text = new JTextField(32);
JButton send = new JButton("Send");
send.addActionListener(new SendButtonListener());
panel.add(scroll);
panel.add(text);
panel.add(send);
frame.getContentPane().add(panel);
frame.setSize(500,500);
frame.setVisible(true);
try {
socket = new Socket("77.126.189.65",5005);
} catch (Exception e) {
e.printStackTrace();
}
Thread thread = new Thread(new ClientReader());
thread.start();
}
public static void main(String[] args) {
Client client = new Client();
}
class SendButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println(text.getText());
writer.flush();
text.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
class ClientReader implements Runnable {
public void run() {
try {
InputStreamReader stream_reader = new InputStreamReader(socket.getInputStream());
BufferedReader reader = new BufferedReader(stream_reader);
while(true) {
String str = reader.readLine();
if(str==null)
continue;
chat.setText(chat.getText() + str + "\r\n" );
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I also tried this tool. When I run the MainServer file and try the tool, I get a positive answer. I also get a positive on my own Eclipse. When my MainServer makes a successful connection, it prints a message about it using these lines:
Socket socket = server_socket.accept();
System.out.println("server connected to " + socket.getInetAddress());
So every time I'm clicking the "check" button in the tool above, I get a message in my Eclipse console (system.out.println part):
server connected to /69.163.149.200
Therefore I think the problem is probably not connected to the MainServer or the portforwading/firewall/static IP.
I also thought maybe the problem occurs because I'm trying connecting from my own router device to my own router. I will leave the MainServer file open for the next half hour so if someone can run the Client.java on his computer it will be helpful.
What you trying to do is a bit weird but it is possible.
You just need to know if your router supports NAT Loopback / NAT Reflection and activate it.
NAT-loopback
Also known as NAT-hairpinning or NAT-reflection. NAT-loopback is a
feature in many consumer routers which allows a user to connect to
its own public IP address from inside the LAN-network. This is
especially useful when a website (with domain) is hosted at that IP
address.
You won't be able to do this without configuring your router appropriately. Most routers do not allow (by default) incoming connections on their external (WAN) port. If you want to allow this, you'll need to go into your router configuration and configure it to allow connections on the external IP for the specific port you are using. Then, you'll have to configure the router to redirect that incoming connection from the external IP address/port to the internal IP address/port of your actual server.
This is frequently how online gamers set up servers in their own home. It is also how many people connect to their own internal networks from the outside world.
Before anything, set up a static IP (like 192.168.1.6) internally.
If youu want to connect via an external IP, there are two ways:
If you have a router, use port forwarding.
If you have a dongle, no need to port forward; you can directly access the server. Just give the dongle's external IP (to find that, use a what's-my-IP service like this one) and a port number (any). (Dongles are not blocked by any ISP.)
You can add your internal IP address along with your server name to /etc/hosts, for example, if you have external IP 10. 10. 123. 123, and with the server name YOURCOMPUTER_1.XXX.XXX, you want to connect inside network, you can add:
127.0.0.1 YOURCOMPUTER_1.XXX.XXX to your /etc/hosts
Here is the code
I have written a server and client. But when i run them, (as you can see in the last program), I get the following error:
Whoop s! java.net.BindException: Address already in use 6666
6666 is the port no. i specified.
import java.net.*;
import java.io.*;
import java.lang.*;
public class processSendHelper
{
Process p;
String address;
int port;
long msg_data;
processSendHelper(int pid, int current_round, long address, long msg_data, int port)
{
try
{
ServerSocket sSoc = new ServerSocket(port);
Socket inSoc = sSoc.accept();
msg_Thread msgT = new msg_Thread(inSoc, msg_data);
msgT.start();
Thread.sleep(5000);
sSoc.close();
}
catch(Exception e)
{
System.out.println("Whoop s! " + e.toString());
}
}
}
/* sends out (or rather just makes available) the provided msg
* */
class msg_Thread extends Thread
{
Socket threadSoc;
long msg_data;
msg_Thread (Socket inSoc, long msg_data)
{
threadSoc = inSoc;
this.msg_data = msg_data;
}
public void run()
{
try
{
PrintStream SocOut = new
PrintStream(threadSoc.getOutputStream());
SocOut.println(msg_data);
}
catch (Exception e)
{
System.out.println("Whoops!" + e.toString());
}
try
{
threadSoc.close();
}
catch (Exception e)
{
System.out.println("Oh no! " +
e.toString());
}
}
}
import java.net.*;
import java.io.*;
public class processReceiveHelper
{
Socket appSoc;
BufferedReader in;
String message;
String host;
int port;
processReceiveHelper(String host,int port)
{
try
{
appSoc = new Socket(host,port);
in = new BufferedReader(new InputStreamReader(appSoc.getInputStream()));
message = in.readLine();
System.out.println(message);
/* Tokenizer code comes here
* Alongwith the code for
* updating the process object's
* data
* */
}
catch (Exception e)
{
System.out.println("Died... " +
e.toString());
}
}
}
public class Orchestrator
{
public static void main(String[] args)
{
processSendHelper psh = new processSendHelper(1, 2, 1237644, 6666, 2002);
processReceiveHelper prh = new processReceiveHelper("localhost", 2002);
}
}
EDIT:
I found the problem. The reason was that i was running both the server and client from the same main program.
the following worked:
That means there is already an application operating on port 6666 preventing your Java application using it. However, it is equally possible there is a running process of your Java application still holding onto 6666. Terminate any running java processes and try re-running the code - if it still fails then you have some other application using 6666 and you would be better using a different port.
That means that the port 6666 is already being used. There are two main causes/solutions for this:
Some other program is using that port. Solution: Choose a different port.
Your old Java program is hanging and still "using" that port. Close all of your hanging Java programs and try again. If that doesn't solve your problem, choose a different port.
Does it happen when you run the program for the second time? You may want to setReuseAddress(true) on this socket.