so today I've tried to install Citadel Email server on a raspberry pi which went ok but unfortunantly I cannot reach it from outside LAN.
I've tried to pinpoint the problem and use scanner tools that look for open ports like these :https://www.whatsmyip.org/port-scanner/
I've verified that my public IP adress is the same as my domain returns. Which indeed it is.
I've checked port forwarding severel times.
Last but not least I've wrote this java code to have a really simple example:
package main;
import java.io.IOException;
public class Main {
public static void main(String... args){
try {
Server server = new Server(8080);
Client client = new Client(8080);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package main;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private boolean stop = false;
public Server(int port) throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
Runnable runnable = new Runnable() {
#Override
public void run() {
while(stop == false) {
try {
Socket socket = serverSocket.accept();
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("Hello World!");
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
String input = inputStream.readUTF();
System.out.println("Client wrote: " + input);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable, "server executor");
thread.start();
}
public void stop(){
this.stop = true;
}
}
package main;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client {
public static final String LOCALHOST = "localhost";
public static final String KIRAZUKE = "---";
public static final String PUBLIC_IP_4 = "---";
public Client(int port) {
try{
doTest(LOCALHOST, port);
} catch (IOException e) {
e.printStackTrace();
}
try{
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try{
doTest(KIRAZUKE, port);
} catch (IOException e) {
e.printStackTrace();
}
try{
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try{
doTest(PUBLIC_IP_4, port);
} catch (IOException e) {
e.printStackTrace();
}
}
private void doTest(String host, int port) throws IOException {
System.out.println("Opening to: " + host);
Socket socket = new Socket(host, port);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("Hello dear Server ... calling from " + host + " ... over.");
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
String string = inputStream.readUTF();
System.out.println("Response from server after " + host + " call: " + string);
}
}
So I've replaced the domain name and my public ip with dashes for privacy reasons. But what happens is that when using the localhost connection everything works fine the server prints the text sent by the client and vise versa. While using either the public IP or Domain name it fails due to time out.
What could be reasons that any incoming traffic is blocked altough port forwarding is enabled for the 8080 port (and other ports that I tried) ?
Note: I've also called my ISP, according to them they "don't block anything". Additionally I tried port forwarding port 3389 and tried remote desktop to my pi but that also failed.
Thanks in advance :)
Related
I'm working on a program involving a multithreaded server, in which I want messages sent by clients to be echoed back to every client currently connected to the server. It doesn't exactly do this. I will send a message from a client to the server, and it will echo back to that same client. Not to the other client. Let's say, with one client I sequentially type "One" then "Two" then "Three". The exchange will be something like this:
Client 1: "One"
Echo from Server ON Client 1's console: "One"
Client 1: "Two"
Echo from Server ON Client 1's console: "Two"
Client 1: "Three"
Echo from Server ON Client 1's console: "Three"
This part does what it should. But absolutely nothing happens on Client 2's console. Let's say the exchange above has already happened. Client 2's screen will still be blank. I will then type something in Client 2, let's say "Test". The server will respond to Client 2 with "One". Let's say I type "Test" again in Client 2. The server will respond with "Two". You get the idea. I'm not sure why it's doing this. I have three files involved, The Client, The Server, and one meant to manage connections between them.
EDIT: I THINK I KNOW THE PROBLEM! On line 43 in client, the console expects some user input before it will proceed. Which I THINK is why when the first client sends user input, it gets a correct reply, but the second one doesn't: because the second client didn't enter anything in the console, and it's still waiting for some input in order to proceed. Any ideas on how to work around this?
Client:
package client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
//The socket for the client
Socket sock;
//The stream to read incoming data
DataInputStream din;
//The stream to send outgoing data
DataOutputStream dout;
public static void main(String[] args) {
//Create a new client
new Client();
}
public Client() {
try {
//Activate the socket to the host and port
sock = new Socket("localhost", 4444);
//Open the input and output streams
din = new DataInputStream(sock.getInputStream());
dout = new DataOutputStream(sock.getOutputStream());
//Start listening for user input
listenIn();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void listenIn() {
//Monitors the console for user input
Scanner userIn = new Scanner(System.in);
while(true) {
//While there is nothing left to read from the console
while(!userIn.hasNextLine()) {
try {
//Ensures resources aren't constantly being used by listening for input
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Get line from user input
String input = userIn.nextLine();
//if user exits the client, break the loop and exit the program
if(input.toLowerCase().equals("quit")) {
break;
}
try {
//outputs user input to Server
dout.writeUTF(input);
//Flushes all data out of the data output stream's buffer space
dout.flush();
//While there's nothing to read from the input stream, save resources
while(din.available() == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//When there's incoming data, print it to the console
String reply = din.readUTF();
System.out.println(reply);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
//Close all the I/O streams and sockets, so there aren't memory leaks
try {
din.close();
dout.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
//The server's socket
ServerSocket sSock;
ArrayList<ServerConnection> connections = new ArrayList<ServerConnection>();
boolean run = true;
public static void main(String[] args) {
//Create a new server
new Server();
}
public Server() {
try {
//Initialize the server socket to the correct port
sSock = new ServerSocket(4444);
//While the socket should be open
while(run) {
//Initialize the client socket to the correct port
Socket sock = sSock.accept();
//Create a new server connection object between the client socket and the server
ServerConnection sConn = new ServerConnection(sock, this);
//Start the thread
sConn.start();
//Add the connection to the arraylist
connections.add(sConn);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server Connection:
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class ServerConnection extends Thread{
Socket sock;
Server server;
DataInputStream in;
DataOutputStream out;
boolean run = true;
//Create the server connection and use super to run it with Thread's constructor
public ServerConnection(Socket socket, Server server) {
super("ServerConnectionThread");
this.sock = socket;
this.server = server;
}
public void sendOne(String text) {
try {
//Write the text to the output stream
out.writeUTF(text);
//Flush the remaining data out of the stream's buffer space
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
//Send a string to every client
public void sendAll(String text) {
/*Iterate through all of the server connections in the server
and send the text to every client*/
for(int i = 0; i < server.connections.size(); i++) {
ServerConnection sc = server.connections.get(i);
sc.sendOne(text);
}
}
public void run() {
try {
//Set the input stream to the input from the socket
in = new DataInputStream(sock.getInputStream());
//Set the output stream to write out to the socket
out = new DataOutputStream(sock.getOutputStream());
//While the loop should be running (as determined by a boolean value)
while(run) {
//While there is no incoming data, sleep the thread to save resources
while(in.available() == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Store the incoming data in a string
String textIn = in.readUTF();
//Send it to all clients
sendAll(textIn);
}
//Close datastreams and socket to prevent memory leaks
in.close();
out.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Like you have done in the server side, you may use a separate thread to take care of incoming data in the client side. That way, the waiting for the user input in the console will not block the incoming data flow.
Here is an idea of how you could implement this.
New ClientConnection:
package client;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
public class ClientConnection extends Thread {
DataInputStream din = null;
public ClientConnection(Socket socket) throws IOException {
this.setName("Client-Thread");
this.din = new DataInputStream(socket.getInputStream());
}
public void run() {
boolean run = true;
while (run) {
// While there's nothing to read from the input stream, save resources
try {
// When there's incoming data, print it to the console
String reply = din.readUTF();
System.out.println(reply);
run = this.isAlive();
} catch (SocketException e) {
System.out.println("Disconnected");
run = false;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
din.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And here is the reformulated Client:
package client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
// The socket for the client
Socket sock;
// The stream to send outgoing data
DataOutputStream dout;
public static void main(String[] args) {
// Create a new client
new Client();
}
public Client() {
try {
// Activate the socket to the host and port
sock = new Socket("localhost", 4444);
// Open the input and output streams
dout = new DataOutputStream(sock.getOutputStream());
//Listening for incoming messages
ClientConnection client = new ClientConnection(sock);
client.start();
// Start listening for user input
listenIn();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void listenIn() {
// Monitors the console for user input
Scanner userIn = new Scanner(System.in);
while (true) {
// While there is nothing left to read from the console
while (!userIn.hasNextLine()) {
try {
// Ensures resources aren't constantly being used by listening for input
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Get line from user input
String input = userIn.nextLine();
// if user exits the client, break the loop and exit the program
if (input.toLowerCase().equals("quit")) {
break;
}
try {
// outputs user input to Server
dout.writeUTF(input);
// Flushes all data out of the data output stream's buffer space
dout.flush();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
// Close all the I/O streams and sockets, so there aren't memory leaks
try {
dout.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
On the server side, you may also consider removing the disconnected clients from the list of connections:
public class ServerConnection extends Thread {
...
public void run() {
try {
...
} catch (SocketException e) {
System.out.println("Client disconnected");
server.connections.remove(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I hope this helps.
Scenario:
a) Persistent connections
b) Manage each server-client communication individually
c) Protect System from propagating exceptions/errors
I tried to created two instances of server socket listeners using the following code :
SimpleSocketServers.java
public class SimpleSocketServers {
public static void main(String[] args) throws Exception {
int port1 = 9876;
SimpleSocketServer server1 = new SimpleSocketServer(port1);
server1.startAndRunServer();
System.out.println("Servers : server1 Listening on port: " + port1);
int port2 = 9875;
SimpleSocketServer server2 = new SimpleSocketServer(port2);
server2.startAndRunServer();
System.out.println("Servers : server2 Listening on port: " + port2);
}
}
and
SimpleSocketServer.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleSocketServer {
private ServerSocket serverSocket;
private int port;
public SimpleSocketServer(int port) {
this.port = port;
}
public void startAndRunServer() {
try {
System.out.println("Starting Server at port " + port + " ...");
serverSocket = new ServerSocket(port);
System.out.println("Listening for client connection ...");
Socket socket = serverSocket.accept();
RequestHandler requestHandler = new RequestHandler(socket);
requestHandler.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class RequestHandler extends Thread {
private Socket socket;
RequestHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
System.out.println("Client Request Response being processed...");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}
But, it creates only one instance as control is not returning from the constructor of first instance. Is there any possibility to get back control and run both instances of server socket listeners simultaneously? (ps: Pardon me, if it is wrong or trivial!)
Use 2 Different Threads, Listening To 2 Different Ports.
Thread ServerThread1 = new Thread(new Runnable() {
#Override
public void run() {
ServerSocket ServerSocketObject = null;
while(true)
{
try {
ServerSocketObject = new ServerSocket(Your_Port_Number1);
Socket SocketObject = ServerSocketObject.accept();
// Your Code Here
SocketObject.close();
} catch (IOException e) {
try {
ServerSocketObject.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
});
Thread ServerThread2 = new Thread(new Runnable() {
#Override
public void run() {
ServerSocket ServerSocketObject = null;
while(true)
{
try {
ServerSocketObject = new ServerSocket(Your_Port_Number2);
Socket SocketObject = ServerSocketObject.accept();
// Your Code Here
SocketObject.close();
} catch (IOException e) {
try {
ServerSocketObject.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
});
ServerThread1.start();
ServerThread2.start();
You need to have SimpleSocketServer implement Runnable; start a thread with itself as the Runnable in the constructor; and run an accept() loop in the run() method. At present you're blocking in the constructor waiting for a connection, and your servers will also only handle a single connection.
The more interesting question is why you want to provide the same service on two ports.
I just started using Sockets, and for my current project I need to be able to control my program from a client, however if my project-partner wants use his client at the same time, the server doesn't send him the "You are connected" message as shown in the connection class. So I assume the server doesn't accept mutiple clients at the same time. I have tried using a Thread of the class Connection, but that also doesn't send the message "You are connected" to the second Client. What am I doing wrong here?
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Listener extends Thread{
private ServerSocket server;
private int PORT;
public boolean running;
public Listener(int port){
try{
this.PORT = port;
this.server = new ServerSocket(PORT,10);
}catch (IOException e) {
System.out.println("Could not create serverSocket...");
}
}
#Override
public void run() {
this.running = true;
try{
waitForConnection();
}catch(IOException e){
System.out.println("Could not accept connection request..");
run();
}
}
public void dispose(){
try{
System.out.println("DISPOSE");
running = false;
server.close();
} catch (IOException i) {
System.out.println("Could not close ServerSocket");
}
}
private void waitForConnection() throws IOException{
while(running){
System.out.println("Waiting for connection");
Socket client = server.accept();
Runnable connection = new Connection(client);
new Thread(connection).start();
}
}
}
This is the Thread I'm using to have multiple users connect at the same time:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Connection extends Thread {
Socket connection;
private ObjectOutputStream output;
private ObjectInputStream input;
private boolean running;
public Connection(Socket connect){
this.connection = connect;
try {
setupStreams();
whileListening();
} catch (IOException e) {
System.out.println("could not connect to: "+ connection.getInetAddress().getHostName());
}
}
public void dispose(){
try{
output.close();
input.close();
connection.close();
running = false;
}catch(IOException ioException){
ioException.printStackTrace();
}
}
private void whileListening(){
String message = "You are connected! ";
sendMessage(message);
do{
try{
message = (String) input.readObject();
checkMessage(message);
}catch(ClassNotFoundException classNotFoundException){
sendMessage("tf did you send? ");
}catch (IOException e) {
dispose();
run();
}
}while(!message.equals("Client - END") && running == true);
}
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
}
private void sendMessage(String message){
try {
output.writeObject("Server - " + message+"\n");
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void checkMessage(String text){
//check the message
}
}
EDIT: Addittional information
Before the first client connects, the server console says "Waiting for connection", then when the first client connects, the client console says "You are connected" and, when a second client connects, the console is black, when I close the first client, the second client console says "You are connected" and the server console says "Waiting for connection", then if I close the second client aswell, the server console says "Waiting for connection" again.
In your constructor of the public class Connection extends Thread you do this whileListening()stuff, so your constructor never ends, you need to override the run() function and do that there
#Override
public void run() {
while(true) {
try {
whileListening();
} catch(Exception e) {}
}
}
like so, it should do the trick.
I think you must accept first, after that you start the thread.
For example, let's suppose something like this
in your main class, you get the ServerSocketFactory and then the ServerSocket.
then, inside an (endless) loop, you wait for a new Socket returned by the ServerSocket.accept()
Only after that, you start your thread
Here's an example from a SSLServerSocket, which is pretty much the same logic (consider it a pseudo-code)
SSLContext sc = SSLContext.getInstance("TLS");
(...)
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(portNumber);
while (listening) {
SSLSocket c = (SSLSocket) s.accept();
log.info("Serving");
new SimpleSSLServerSocketThread(c).start();
}
My program works fine and many users can connect and send commands to the server.
But when a user spams the server with commands the server blocks out all other clients and the server doesn't receive messages from clients other than the one that spammed.
Why is this?
TCPAccept Connections
package game.server;
import java.io.IOException;
import java.net.Socket;
public class TCPAcceptConnections implements Runnable
{
public static Socket clientSocket = null;;
int clientID = -1;
public void run()
{
while(Main.TCP)
{
try
{
clientSocket = TCPServer.serverSocket.accept();
System.out.println("Client Connected.");
clientID++;
new TCPClientManager(clientSocket, clientID).run();
}
catch (IOException e)
{
System.out.println("Couldn't create client socket.");
System.exit(-1);
}
}
}
}
TCPClientManager:
package game.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class TCPClientManager implements Runnable
{
Socket client;
int clientID;
static PrintWriter out;
static BufferedReader in;
String inputLine, outputLine;
boolean destroy = false;
public TCPClientManager(Socket cs, int id)
{
try
{
client = cs;
clientID = id;
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch(IOException e)
{
e.printStackTrace();
}
}
public void run()
{
System.out.println("Created TCPManager for client.");
String command;
while(!destroy)
{
try
{
if((command = in.readLine()) != null) //If received something
{
System.out.println("Commad received: " + command);
System.out.println(" " + Commands.proccessCommand(command));
System.out.println("Command proccessed");
}
else
{
client.close();
destroy = true;
}
} catch (IOException e)
{
try
{
client.close();
} catch (IOException e1)
{
e1.printStackTrace();
destroy = true;
}
System.out.println("Client lost connection.");
destroy = true;
}
}
System.out.println("TCPManager for client destroyed.");
}
}
Commands:
package game.server;
public class Commands
{
public static String proccessCommand(String command)
{
if(command.equalsIgnoreCase("cp"))
{
System.out.println("Creating player...");
System.out.println(" Retrieved client");
return "Player Created";
}
else
{
return "Unkown command: " + command;
}
}
}
If you get an unknown command, you should log it and close the connection.
But you have a more severe problem. You aren't stopping the client handler when it reads null. So once a client disconnects the read will spin futilely forever. If readLine() returns null you must close the socket and exit the loop. If you get any IOException you must also close the socket.
My final project for a class is to put together a game, including multiplayer. So I started trying to figure out java networking, and I'm kind of stuck.
Each of the two game clients needs to be able to send and receive messages to and from the other client.
The way I figured I would handle this is that I have a NetworkServer and NetworkClient objects that runs in their own threads.
I was thinking that I would just start them from my main game application, but I wanted to do some testing first, so I set this project up:
NetworkClient:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
public class NetworkClient extends Thread {
Socket server;
ObjectOutputStream out;
Timer timer;
public NetworkClient(String hostname, int port) throws IOException
{
server = new Socket(hostname, port);
out = new ObjectOutputStream(server.getOutputStream());
timer = new Timer();
timer.schedule(new SendTask(), 0, 1*1000);
}
public void sendData(Integer b) throws IOException {
out.writeObject(b);
}
class SendTask extends TimerTask {
Integer i = new Integer(1);
public void run() {
System.out.println("Client: Sending Integer: " + i.toString());
try {
sendData(i);
i = new Integer(i.intValue()+1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // run()
} // class SendTask
}
NetworkServer:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class NetworkServer extends Thread {
private ServerSocket serverSocket;
private Socket client;
private Integer i;
private ObjectInputStream in;
public NetworkServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
//serverSocket.setSoTimeout(10000);
}
public void run()
{
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
client = serverSocket.accept();
System.out.println("Just connected to " + client.getRemoteSocketAddress());
in = new ObjectInputStream(client.getInputStream());
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
while(true)
{
try
{
i = (Integer) in.readObject();
System.out.println("Server: Received the integer: " + i.toString());
}
catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}
catch(IOException e)
{
e.printStackTrace();
try { client.close();} catch (IOException e1) {}
break;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Network (The thing I'm using to try and test this):
import java.io.IOException;
public class Network {
NetworkClient client;
NetworkServer server;
public Network() throws IOException {
server = new NetworkServer(6066);
server.start();
client = new NetworkClient("192.168.1.196", 6066);
client.start();
}
public static void main(String [] args)
{
try
{
Network n = new Network();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
I have the timer in there to facilitate sending data from the client to the server, which would normally be done by my game, but since I'm testing I had to have it send somehow.
When I run this where the client and server are talking to each other, I get both the Sent and Received messages.
When I put it on my laptop (and change the IP in NetworkClient to match my desktop, and vice versa on my desktop) and run it in both places, the client on the desktop sends to the server on the laptop, but the client on the laptop does not send to the server on the desktop.
And at some point during the running, I get an exception about that client's connection being reset by peer, though the working client/server connection continue.
So, I guess my question is, Does anyone know why it works in one direction but not bidirectionally?
FIXED!!
Edit: Gah, I figured it out. It had to do with the timing on starting the two servers.
I changed Network to:
import java.io.IOException;
public class Network {
NetworkClient client;
NetworkServer server;
public Network() throws IOException {
startServer();
startClient();
}
private void startServer() throws IOException {
server = new NetworkServer(6066);
server.start();
}
private void startClient(){
boolean isConnected = false;
while (!isConnected) {
try {
client = new NetworkClient("192.168.1.196", 6066);
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
continue;
}
isConnected = true;
}
client.start();
}
public static void main(String [] args)
{
try
{
Network n = new Network();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Edit your Firewall. Make sure that java.exe has inbound and outbound traffic enabled. Also, add a rule to your Firewall for port 6066.