I have two PCs in one network that I want to connect. One of them should send a notification to the other via TCP. One the one PC I have a "server" (Python script) socket which waits for the "client"(Jar file) to send a specific String and then it gives me a notification. This works perfectly fine when I'm trying it out one one PC. But when I want to do the intended action the "client" PC's .jar gives me an error that the connection is refused. Do I have to open a specific port on the other PC or what else could cause trouble? One PC runs Fedora the other Windows 8
"Server Code"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 5005))
s.listen(1)
try:
while True:
komm, addr = s.accept()
while True:
data = komm.recv(1024)
if data == "$":
noty()
if not data:
komm.close()
break
finally:
s.close()
"Client" Code
public static void main(String[] args) throws Exception {
Socket socket = new Socket("192.168.178.25", 5005);
OutputStream out = socket.getOutputStream();
String dat = "$";
out.write(dat.getBytes());
socket.close();
}
Your server is probably binding to the wrong interface,
calling
s.bind(("", 5005))
Without setting an interface will allow the program to pick what ip address / interface it will connect to.
Since your client is trying to connect to ("192.168.178.25", 5005); you may want to put an IP address into the bind call to prevent the server picking the wrong ip interface.
Example:
s.bind(("192.168.178.25", 5005))
if its permission denied then something is blocking your connection with the computer. i would try to open a port and see if that works. if you want an example of java sockets you can take a look at my SUPER Tic-Tac-Toe Multiplayer it uses java sockets to send strings to the clients as a way to represent what actions the clients should take.
Related
I'm writing a ServerSocket in java. I want to send some special content to client connecting to me through telnet. I want to send other content if he/she connects through Browser and etc. Is there any way to find out that user is connecting to me with telnet?
My code :
public void handleConnection(Socket socket) throws IOException {
String author = "Ehsan Akbari";
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
if(checkoutClientType(socket)=="telnet")
out.println("You are connecting through telnet :\)");
else
out.println("You are not connecting through telnet :|");
}
What should be the definition of checkoutClientType(Socket s);?
You cannot tell what program is on the other side of a socket by examining the socket itself. There is no test or operation you can perform on the socket that will distinguish the client program.
The only hope is to examine the data being transmitted to see if it matches an expected pattern, but for that you have to have some data transmitted. It might be possible to tell if the remote is telnet if you were to send a Telnet Protocol command such as AYT (Are You There), but that would probably not sit well with a different client such as a browser.
If you were able to proxy the data between the client and a handling process or thread and examine it you might be able to eventually determine if it was Telnet, but probably not, and probably not immediately.
I am using UDP broadcast for interservice communication The server is in Python and I can see the UDP messages using this code:
import sys
import socket
HOST = ''
PORT = 9002
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
s.bind((HOST,PORT))
while True:
try:
message = s.recv(8192)
print("Got data: " + message)
except KeyboardInterrupt:
sys.exit()
I can run as many of these clients simultaneously as I want on the same machine.
I'm trying to implement a similar client in Java using the DatagramSocket class, but I keep getting an "address already in use" error. Evidently I need to construct it differently than I am currently:
DatagramSocket socket = new DatagramSocket(broadcastPort);
Is it possible to get the same behavior as the Python code?
Try this:
// create an unbound socket
DatagramSocket socket = new DatagramSocket(null);
// make it possible to bind several sockets to the same port
socket.setReuseAddress(true);
// might not be necessary, but for clarity
socket.setBroadcast(true);
socket.bind(new InetSocketAddress(9002));
The null argument to the constructor is the key here. That wisdom is hidden in the second paragraph of the javadoc for the DatagramSocket(SocketAddress bindAddress) constructor:
if the address is null, creates an unbound socket.
Address already in use probably means you haven't properly terminated your programs. If you're using Eclipse, make sure you check all your open consoles and terminate all of them. (Top right corner, blue box - click it and it'll show all running programs)
In Eclipse, just because you "run" your program again, it doesn't terminate the previous one(s).
Another possible issue is that you may be using the same port as your python server. 2 Applications can't claim the same port, so just change the port number if that is the case.
Edit: Use a MulticastSocket.
The app uses sockets to connect to the computer but will only connect if the computer is connected to the network by an ethernet cable. I've tried disabling the firewalls but that makes no difference.
The code for the server on the computer:
int port = 7936;
while(true){
ServerSocket server = new ServerSocket(port);
System.out.println("Waiting for client ...");
Socket client = server.accept();
System.out.println("Client from "+client.getInetAddress()+" connected");
InputStream in = client.getInputStream();
and the code for the client on the app:
Socket socket = new Socket(address,7936);
OutputStream out = socket.getOutputStream();
String action = "2";
byte[] actByte = action.getBytes();
out.write(actByte);
socket.close();
Address is defined by user input and all the permissions needed have been set in the manifest xml file.
Thanks for the help.
Edit
Sorry for the delay in responding to the answers given. I have since been able to try the program on a different network and it works with the computer connected wirelessly so it looks like the issue was with the network rather than the code.
Thanks to everyone for answering and I'm sorry it took me so long to respond.
As others have mentioned, more information is needed. When you disconnect the computer from the wired connection, I assume it is switching over to wifi and you've verified that you are online. Your computer is likely to get a different IP address if you're DHCP as the interface changed and so wouldn't the MAC address.
Check the address on the computer and verify you have the right address.
What I'm thinking is that the socket is not bound to the IP address you think it is. You may wish to try using the TcpListener class, that way you can bind it to the IP address (network adapter) you want.
This question seems like something very obvious to ask, and yet I spent more than an hour trying to find an answer.
First I host and wait for someone to connect. Then, from another instance of the application, I try to connect with a socket - for the constructor, I use InetAddress, port. The port is always right, and everything works if I use "localhost" for the address. However, if I type my IP (the one I got from Googling "what is my ip"), I get an IOException. I even sent the application to someone else, gave him my IP, and it didn't work.
The aim of the application is to connect two computers. It's in Java. Here is the relevant code.
Server:
ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();
Client:
InetAddress a = InetAddress.getByName(ip);
Socket s = new Socket(a, port);
I don't get past that. Obviously, the values of int port and String ip are taken from text fields.
Edit: the purpose of my application is to connect two non-local computers.
As mentionned by Greg Hewgill, if you are behind a NAT Device (Router, etc...) you will have to do some Port Forwarding.
Basically, your public IP Address that you get from using "What is my IP" from google is your public IP Address, but since you are using a router with multiple computers connected to it, there is a protocol that maps multiple computers to a single public address called NAT.
What you'll need to do is tell your router to forward the incoming packets on a certain port to a certain computer.
The way to do this is highlighted in this article http://www.wikihow.com/Port-Forward
I'm making a client/server pair with sockets to send and receive data back and forth. When I'm at home on my internet using two separate machines for client/server, it works fine as expected. Data is transmitted and so forth.
However, today when I was working at a local coffee shop (Second Cup, in case that's relevant), this did not work. I kept getting the following errors: either connection timed out, or no route to host.
Here is the relevant code:
Server:
public class TestServer {
public static void main(String[] args) throws Exception {
TestServer myServer = new TestServer();
myServer.run();
}
private void run() throws Exception {
ServerSocket mySS = new ServerSocket(9999);
while(true) {
Socket SS_accept = mySS.accept();
BufferedReader myBR = new BufferedReader(new InputStreamReader(SS_accept.getInputStream()));
String temp = myBR.readLine();
System.out.println(temp);
if (temp!=null) {
PrintStream serverPS = new PrintStream(SS_accept.getOutputStream());
serverPS.println("Response received");
}
}
}
}
Client: (the relevant part)
//sends a command to the server, and returns the server's response
private String tellServer(String text) throws Exception {
mySocket = new Socket("192.168.0.XXX", 9999); //the IPv4 address
//use the socket's outputStream to tell stuff to the server
PrintStream myPS = new PrintStream(mySocket.getOutputStream());
myPS.println(text);
//the following code will get data back from the server
BufferedReader clientBR = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
String temp = clientBR.readLine();
if (temp!=null) {
return temp;
} else {
return "";
}
}
It's pretty much as simple as can be. Again, as mentioned, at home on my internet it works fine - just do ipconfig, grab the IPv4 address, and put it in for the client. In coffee shops with free wifi, it doesn't work. I even fiddled with many different ports just in case.
Thanks for any help, I'm new to sockets and finding this confusing.
192.168.x.y is a local address. source
You need your home machines ip address as the INTERNET sees it.
When you're home next, go to http://www.whatismyip.com/ and see what it thinks you are.
Note that you might need to go onto your router and route traffic from your router to your machine for port 9999, since that's what you'll probably be hitting.
When you're running both the server and client on the same machine, you could use the loopback address, 127.0.0.1, when out at the coffee shop.
Using the loopback address and running the server and client on the one machine should work all the time, whether at home or out.
You could check your IP address as suggested by Total, but that will only stay the same if you have a static IP. If you aren't sure if you have a static or dynamic IP address, you probably have a dynamic IP address but you should check your IP address a few times over a week or so to observe any change.
Another alternative is to consider a free dns server e.g. http://freedns.afraid.org/ , set a job to update your IP address regularly with that service and use whatever domain name you have chosen to access your local server.
With either method of accessing your home network remotely, you'll need to forward traffic on 9999 to the relevant machine on your home network.
HTH :)