So far I have achieved making server/client relations on the same computer by parallelly running different java classes. As I don't want to overcomplicate this question, I will post my simplified code which works perfectly fine.
Server:
public class Server {
public static final int PORT = 9090;
public static void main (String[] args) {
try {
ServerSocket serverSocket = new ServerSocket (PORT);
Socket client = serverSocket.accept ();
System.out.println ("Client connected!");
} catch (IOException ioException) {
ioException.printStackTrace ();
}
}
}
Client:
public class Client {
public static final int PORT = 9090;
public static final String IP_ADDRESS = "127.0.0.1";
public static void main (String[] args) {
try {
Socket socket = new Socket (IP_ADDRESS,PORT);
} catch (IOException ioException) {
ioException.printStackTrace ();
}
}
}
After I run them, I get the expected output - console in class Server prints "Client connected!".
Like any other curious programmer, I decided to try out the same program on my two laptops. One laptop has client code, while second has server code. Of course, I had to change "127.0.0.1" or "localhost" to ip address my server laptop has by typing on google "what is my IP address". I just copied that new IP address into IP_ADDRESS variable and hoped it would work the same. Unfortunately, it didn't happen. My client laptop looks as if it never connected to server laptop, because server laptop never printed message "Client connected!". What am I missing? It looks so easy, yet it doesn't work. Could someone help me solve this?
P.S. I don't want to share my IP address due to privacy reasons, but it was the first number that pops when any of you google: what is my IP address?
If you are on a local network, you don't have to take your public IP. You need to find your local IP (if you are on linux, a simple "ip a" and you'll have your IP address, if you are on windows )
If you are not on a local network, you could open your router' settings to open the 9090 port but I STRONGLY discourage you to do something like that for security reason.
Related
I have a problem that's driving me crazy.
Let's say I have client and server (TCP connection):
public class ServerTCP {
public static void main(String args[]) throws IOException {
ServerSocket srvr = new ServerSocket(4380);
Socket skt = srvr.accept();
System.out.print("Client has connected!\n");
skt.close();
srvr.close();
}
}
public class ClientTCP {
public static void main(String args[]) throws IOException {
Socket skt = new Socket("myIPaddress", 4380);
}
}
If I replace IP address from ClientTCP with "localhost", everything works fine. When I start ServerTCP, go to http://www.yougetsignal.com/tools/open-ports/, enter 4380 and hit Check, I got message from terminal "Client has connected!". So that should mean that port forwarding is right and I can receive connections. But, when I try to connect from ClientTCP I cannot do it. No matter what I do (disabled ufw, tried different ports), it's just stuck and I eventually I get connection timeout.
I also tried same thing with Netty, same problem occurs. I am using XUbuntu
16.04 LTS, if that helps. I have no idea what else should I do.
I'm trying to build a basic client-server application.
When I run both the server and the client on the same computer both manage to connect without a hitch but if I try to do so from different computers (desktop and laptop) the connection doesn't get though. The server isn't even aware that someone tried to connect to it while the client timeouts after a while. At first I assumed that it's a firewall problem but disabling the firewall completely on the server PC did not help. Tried changing ports and checked on multiple computers. Any ideas what could cause this?
I control both the server and the client and can change the code of both if necessary. The server always runs on the same PC and I'm connecting to it directly using hardcoded IP address.
This is the code of the client sending random int to the server.
public static void main(String[] args) {
Socket s = new Socket();
try {
s.connect(new InetSocketAddress("123.45.67.891", 8084), 5000);
s.getOutputStream().write(42);
s.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
The server is slightly more complicated but considering the fact that they manage to connect while being run from the same PC I assume that the problem isn't with it.
edit: Server code (Thread per client. There shouldn't be too many of those)
public void run() {
try {
serverSocket = new ServerSocket(listenPort); //integer
} catch (IOException e) { ... }
while (shouldRun) {
try {
Socket clientSocket = serverSocket.accept(); // Blocked here while trying to connect from remote computer
//Never gets here
ConnectionHandler newConnection = connectionHandlerCreator.create(clientSocket);
connectionHandlers.add(newConnection);
newConnection.initialize();
new Thread(newConnection).start();
} catch (IOException e) { ... }
}
}
Initialize consists of the following (which latter used for I/O).
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
The problem is probably on your server side though: you have to make it respond to all ip's not just local one, by using the constructor:
ServerSocket(int port)
it will default accepting connections on any addresses which is not the case if you specified an IP
So I created a basic client-server program in java. It starts out like this:
Client connects to Server
Server asks for Client's name
Client responds with name
Server greets Client
After this, Client speaks and the Server repeats the words back
I got this to work without too much trouble using this tutorial. The problem comes whenever I try to introduce multiple clients. I thought that it would work because I'm using multiple threads, however, the second clients just hangs until the first client quits and then it starts it work (the server does accept input from the second client, but it doesn't respond with anything until the first client quits).
Here is the code I'm using:
import java.net.*;
import java.io.*;
public class Server extends Thread {
private ServerSocket listener;
public Server(int port) throws IOException {
listener = new ServerSocket(port);
}
public void run() {
while(true) {
try {
Socket server = listener.accept();
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("What is your name?");
DataInputStream in = new DataInputStream(server.getInputStream());
String user_name = in.readUTF();
out.writeUTF("Hello "+user_name);
while(true) {
String client_message = in.readUTF();
out.writeUTF(client_message);
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int port = 6006;
try {
Thread t = new Server(port);
t.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Can someone explain what I'm doing wrong?
I have looked at the using Runnable instead of Extends Thread, but I ran into even more problems there, so I want to try and work with this first.
Incoming connections are only handled by the line listener.accept();. But after you got a client connected, you're stuck in the while loop. You need to create a new Thread (or Runnable executed on an ExecutorService if you expect high load), and start it, then immediately accept the next connection.
In a nutshell, this is what is going wrong.
You are using exactly ONE thread as the server.
Blocking this thread when you call listener.accept()
This is what you need to do:
Create two classes
1: Server - Similar to what you have now, but instead of doing the actual work of acting as an echo server, it just spawns a new Thread which starts listening on a NEW PORT (which you can select randomly), and sends the client the address for this new port. The client will then get the new port number and would try to connect to the server on the new port.
2: The Echo thread - This starts a new listener on the port passed, and does the job of echoing to whoever is listening.
OR:
You start a UDP server rather than a TCP server, and all this will not matter then, but that is out of the purview of this specific question.
I have searched everywhere to find an answer for this question:
I have a TCP client on my android application that sends an message to the server which is written in Visual Basic .NET Framework 4.
Now i want to send an message from my server to the phone over 3g, it works on wifi and 3g..
private class startserver extends Thread
{
public void server() throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(8765);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence.substring(1));
msgshower = clientSentence.substring(1);
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Received: " + msgshower , Toast.LENGTH_LONG).show();
}
});
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
#Override
public void run() {
try {
server();
} catch (Exception e) {
e.printStackTrace();
}
}
I start it in the OnCreate method
Now i send a message with (VB.NET)
Private Sub sends(ByVal message As String)
Dim tcp As New TcpClient
tcp.Connect(connectedIP, 8765)
Dim bw As New IO.BinaryWriter(tcp.GetStream)
bw.Write(message)
bw.Close()
tcp.Close()
End Sub
On wifi it will arrive, on 3g it wont... any idea's how to do this?
How do other applications archive this?
I think you're having problem with the ip address asigned by your mobile phone operator. The fact that works on wifi, but not on 3G, I think that is because your mobile(when connected through 3G) doesn't have a public IP address.
When you use SocketServer in your mobile, you're opening a port a waiting for others to connect to it. If your IP address is not reachable from internet, it won't happen (it's like having a computer behind a firewall.)
Could you try to implement the server in the VB machine, assuming that it has a public reachable address? This way, the phone wouldn't act as a server, it wouldn't be necessary to have a reachable address, as long as the VB machine has one. Then, you should use Socket class to bind to the server ip and port.
Totally confused by your code list above..
If you want to host a server in VB.NET, you should not use TcpClient class but TcpListener and if you need a better performance, use Socket class directly.
At the Android client side, you should new Socket(server,servPort), when you want to send message, write the outputStream, and read the inputStream to receive message.
I am coding a basic app, a chat that sends message through the network using multicast and unicast, depending on the situation. So far, no problem, until a while ago when I began the MulticastSocket part. I have a BindException when I run this basic code (I removed all my other methods that do not concern the part with my problem) :
private MulticastSocket socket_multicast;
private int port;
private InetAddress multicast_address;
public void setPort(int p) {
port = p;
}
public void setMulticastAddress(String s) {
try {
multicast_address = InetAddress.getByName(s);
} catch (IOException e) {
e.printStackTrace();
}
}
public void joinGroup() {
System.out.println("Port : "+port+"\n #IP : "+multicast_address+"\n");
try {
socket_multicast = new MulticastSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
try {
socket_multicast.joinGroup(multicast_address);
} catch (IOException e) {
e.printStackTrace();
}
}
When I run this piece of code, I have the following error (I put 225.1.1.1 and 4567 in the GUI):
Port : 4567
#IP : /225.1.1.1
java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
at
java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:85)
at java.net.DatagramSocket.bind(DatagramSocket.java:373)
at java.net.MulticastSocket.<init>(MulticastSocket.java:165)
at java.net.MulticastSocket.<init>(MulticastSocket.java:130)
at networkinterface.MulticastIF.joinGroup(MulticastIF.java:61)
No matter which combinason of IP and port I put, always get the same error. I even restarted my computer, it made no changes.
Notes : To test, I do a right click in my class with the main in the Package view, then "Run as -> Java application". Does Eclipse makes some kind of virtual machine when I do that, or only uses the loopback address 127.0.0.1, or whatever ? When I print the result of InetAddress.getLocalHost(); I've got "akee-netbook/127.0.1.1". Since I use Unicast and Multicast, Maybe it only uses the loopback address, and tries to bind on an already-binded address. If so, how can I properly test my app ? I don't know if I am being clear, if not, tell me !
One last thing, Why is there a slash when I print my ip address? Will it be a problem later ? or is it smth that comes from the toString() method?
Are you running this on a linux system? If so, have you compiled multicasting into the kernel or loaded the module for it?
Regarding the toString(), see the javadocs for InetAddress.toString()
Huh, I know where I went wrong. I am using an UDP socket (DatagramSocket) with the #IP/port, and then I try to bind again on the same #IP/port with a MulticastSocket. Because Multicast uses UDP I presumed that I could use the same socket for both Unicast and Multicast traffic, it seems that it doesn't work that way.
Anyway, thank's for your answers and sorry for taking your time over a n00b problem, solved with two characters :
socket_multicast = new MulticastSocket(port);
replaced with
socket_multicast = new MulticastSocket(port+1);
-_-"