Hi I'm new to java socket and I've been trying to create a server socket. I know this question may have been asked but i would like for someone to look at my code please. Can someone please tell me where I'm going wrong because I'm getting an error saying "Address already in use" Help please? I have also realised that with some research that I may have run two servers simultaneously. Can anyone please explain please?Here's the server class and the client class.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class MessageServer {
public static void main(String[] args) throws IOException{
//int port = 25000;
//int port = Integer.parseInt(args[0]);
ServerSocket serverr = new ServerSocket(3456);
while(true){
System.out.println("Waiting for client...");
//ServerSocket serverSocket = new ServerSocket(53705);
//System.out.println("listening on port " + serverSocket.getLocalPort());
Socket client = serverr.accept();
System.out.println("Client from " + client.getInetAddress() + " connected.");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine = in.readLine();
System.out.println("Client said: '"+inputLine+"'");
Writer count = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
byte c [] = count.toString().getBytes();
count.flush();
//server.close();
}
}
}
import java.net.*;
import java.io.*;
public class MessageSendClient {
public static void man(String args[]) throws IOException{
Socket client = new Socket ("localhost", 3456);
System.out.println("Connected to " + client.getInetAddress());
InputStream in = client.getInputStream();
byte c[] = new byte[100];
int num = in.read(c);
String count = new String(c);
System.out.println("Server said: " + count);
client.close();
}
}
Exception stack trace:
Exception in thread "main" java.net.BindException: Address already in use at
java.net.PlainSocketImpl.socketBind(Native Method) at
java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376) at
java.net.ServerSocket.bind(ServerSocket.java:376) at
java.net.ServerSocket.<init>(ServerSocket.java:237) at
java.net.ServerSocket.<init>(ServerSocket.java:128) at
MessageServer.main(MessageServer.java:18)
This has to do with some previous socket (of a previous run of the program) staying alive some time to complete the double ACK on close mechanism. You can bypass that by indicating a specific option to the socket:
socket.setReuseAddress(true);
(where socket is your server socket).
Either:
A previous instance of your code is still running: terminate it.
Something else is listening at the port: bad luck.
A connection port is still in the TIME_WAIT state after the previous instance of your program had exited. Either wait two minutes, or create your ServerSocket as follows:
ServerSocket ss = new ServerSocket(); // create an unbound socket
ss.setReuseAddress(true);
ss.bind(...); // argument(s) left as an exercise for the reader
This error message means some application has already created a socket on the port you specified (3456).
To resolve the problem you need either change this port to some other, or find out which program occupies it and terminate this program. In Linux, you can do this with netstat command:
# netstat -tulpn | grep :3456
For more details on netstat command, see this article.
When you have identified the process using technique I wrote above, you may want to kill it. Let's assume the PID of the process is 1234. Then we gonna need this command:
# kill -9 1234
You may need root privileges to do that.
If none of this helps, it is also possible that some external software is blocking your connections. It can be selinux, it can be network firewall settings - consider checking that too.
The problem lies in that when you tested your code twice you didnt fully kill the previous process.
Related
I've set up a Raspberry Pi 3 and I want to make a program that sends data whenever a button is pushed on my breadboard. I have a Python server running on my RPi, and a Java client running on my Windows laptop. However, whenever I send data to my Java client, it receives the data, and then for some reason, the RPi server closes the program due to "broken pipe". However this cannot be true, because my Java program receives data from the Pi! The Java program then closes due to the Pi server closing. But from what I've read online, Python's "error 32: broken pipe" is triggered when the remote socket closes prematurely!
What's going on here? Why can't I keep my server running?
(PS: The data that my Java program receives is wrong, but it receives data nonetheless. I send "1\n", and I receive null.)
Here is the code for my RPi server program:
import RPi.GPIO as GPIO
from time import sleep
import atexit
import socket
import sys
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5, GPIO.IN)
GPIO.setup(7, GPIO.OUT)
def cleanup():
print("Goodbye.")
s.close()
GPIO.cleanup()
atexit.register(cleanup)
THRESHOLD= 0.3
host= sys.argv[1]
port= 42844
length= 0
def displayDot():
GPIO.output(7,True)
sleep(0.2)
GPIO.output(7,False)
def displayDash():
GPIO.output(7,True)
sleep(0.5)
GPIO.output(7,False)
try:
print("Initializing connection...")
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serverAddress= (host, 42844)
s.bind(serverAddress)
print("Connection initialized!")
print("Waiting for client...")
s.listen(1) #Puts the server socket into server mode
client, address= s.accept()
print(address)
while True:
if not GPIO.input(5):
length+= 0.1
GPIO.output(7,True)
s.sendall('1\n')
print("HELLO??")
else:
if length!=0:
if length>=THRESHOLD:
print("Dash") #displayDash()
else:
print("Dot") #displayDot()
s.sendall('0')
length= 0
GPIO.output(7,False)
except KeyboardInterrupt:
print("\nScript Exited.")
cleanup();
Here's the code for the Java client program:
import java.net.*;
import java.io.*;
public class MorseClient{
public static void main(String[] args) throws IOException{
String hostname= null; //Initialize
int portNumber= 0; //Initialize
try {
hostname= args[0];
portNumber= Integer.parseInt(args[1]);
}
catch(ArrayIndexOutOfBoundsException aiobe) {
System.err.println("ERROR. Please specify server address, and port number, respectively");
System.exit(1);
}
Socket redoSocket;
long initTime;
try(
Socket echoSocket= new Socket(hostname, portNumber);
PrintWriter out= new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in= new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdin= new BufferedReader(new InputStreamReader(System.in));
){
redoSocket= echoSocket;
System.out.println("Connection made!");
String userInput= "";
//Order of priority
//Connection time= 0
//Latency= 0
//Bandwidth= 1
redoSocket.setPerformancePreferences(0,0,1);
//Optimizes reliability
redoSocket.setTrafficClass(0x04);
echoSocket.setKeepAlive(true);
String returned= "";
while(true){
returned= in.readLine();
System.out.println(returned);
if(!(returned.isEmpty())){
System.out.println(returned);
System.out.println("YEP");
}
System.out.println(returned);
if(returned==null){
System.out.println("HAHA");
System.out.println("Attempting to reconnect...");
redoSocket= new Socket(hostname,portNumber);
System.out.println(redoSocket.isConnected());
}
}
}
catch(Exception e){
if(e instanceof ConnectException || e instanceof SocketException || e instanceof NullPointerException)
System.err.println("Connection closed by server");
else
System.err.println(e.toString());
}
}
}
The output for the Pi server is:
python ServerMorse.py 192.168.1.101
Initializing connection...
Connection initialized!
Waiting for client...
('192.168.1.14', 58067)
('192.168.1.14', 58067)
Traceback (most recent call last):
File "ServerMorse.py", in <module>
s.sendall('1\n')
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 32] Broken pipe
Goodbye.
And the output for the Java client:
java MorseClient 192.168.1.101 42844
Connection made!
null
Connection closed by server
Good lord, why are you writing a server with sockets? Use Flask.
http://flask.pocoo.org/
Also, pretty sure s should not be sending all. It should be like this:
conn, addr = server.accept()
conn.sendall(.... # <- this is what sends
Here is some sample code from a server I wrote with sockets once..might be useful:
def server():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
address = ('127.0.0.1', 5020)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(address)
server.listen(1)
conn, addr = server.accept()
...
...
conn.sendall(response_ok(some_stuff))
...
conn.close()
(response_ok is a function I wrote)
I've just started with both java and networking with servers and clients. Although i understand the basics of whats going on, i was struggling to put it all together and do what i wanted to do in the title.
I was able to make this to send a message to the server, however i was wondering how i'd turn the message into a input string from the user, and also how id send multiple messages between the client and server
thanks
SERVER
import java.io.*;
import java.net.*;
public class Server {
//Main Method:- called when running the class file.
public static void main(String[] args){
//Portnumber:- number of the port we wish to connect on.
int portNumber = 15882;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console
DataInputStream dataIn = new DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
//Remember to close the socket once we have finished with it.
soc.close();
}
catch (Exception except){
//Exception thrown (except) when something went wrong, pushing message to the console
System.out.println("Error --> " + except.getMessage());
}
}}
CLIENT
import java.io.*;
import java.net.*;
public class Client {
//Main Method:- called when running the class file.
public static void main(String[] args){
//Portnumber:- number of the port we wish to connect on.
int portNumber = 15882;
//ServerIP:- IP address of the server.
String serverIP = "localhost";
try{
//Create a new socket for communication
Socket soc = new Socket(serverIP,portNumber);
//Create the outputstream to send data through
DataOutputStream dataOut = new DataOutputStream(soc.getOutputStream());
//Write message to output stream and send through socket
dataOut.writeUTF("Hello other world!");
dataOut.flush();
//close the data stream and socket
dataOut.close();
soc.close();
}
catch (Exception except){
//Exception thrown (except) when something went wrong, pushing message to the console
System.out.println("Error --> " + except.getMessage());
}
}}
There are some "problems" with your code.
You should only close the ServerSocket if you are done.
You should handle the newly connected client inside a thread to allow multiple clients to simultaniously "send messages".
1.
you could easily wrap your code inside an while loop.
boolean someCondition = true;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
// repeat the whole process over and over again.
while(someCondition) {
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console
DataInputStream dataIn = new DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
}
//Remember to close the socket once we have finished with it.
soc.close();
}
Now your programm should continue to accept clients. But only one at a time. You can now terminate the Server by stopping the programm or by changing the someCondition to false and accepting the next client.
A bit more advanced would be, to shutdown the ServerSocket to stop the programm and catching the exception inside the while loop.
2.
To allow multiple clients to be handled simultaniously, you should pack the handle part into another Thread.
private ExecutorService threadPool = Executors.newCachedThreadPool();
boolean someCondition = true;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
// repeat the whole process over and over again.
while(someCondition) {
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console in a new Thread.
threadPool.submit(() -> {
DataInputStream dataIn = new
DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
}
}
//Remember to close the socket once we have finished with it.
soc.close();
}
The part inside the threadPool.submit block could be specified as an custom instance of the Runnable interface of as an method, to call it using method reference.
I assumed you are knowing about ThreadPools. They have multiple advantages over Threads
This should get you going for any number of clients.
Note: This is not good designed, but it is for demonstrational porpurses only.
I'm trying to implement a TCP connection, everything works fine from the server's side but when I run the client program (from client computer) I get the following error:
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at TCPClient.main(TCPClient.java:13)
I tried changing the socket number in case it was in use but to no avail, does anyone know what is causing this error & how to fix it.
The Server Code:
//TCPServer.java
import java.io.*;
import java.net.*;
class TCPServer {
public static void main(String argv[]) throws Exception {
String fromclient;
String toclient;
ServerSocket Server = new ServerSocket(5000);
System.out.println("TCPServer Waiting for client on port 5000");
while (true) {
Socket connected = Server.accept();
System.out.println(" THE CLIENT" + " " + connected.getInetAddress()
+ ":" + connected.getPort() + " IS CONNECTED ");
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connected.getInputStream()));
PrintWriter outToClient = new PrintWriter(
connected.getOutputStream(), true);
while (true) {
System.out.println("SEND(Type Q or q to Quit):");
toclient = inFromUser.readLine();
if (toclient.equals("q") || toclient.equals("Q")) {
outToClient.println(toclient);
connected.close();
break;
} else {
outToClient.println(toclient);
}
fromclient = inFromClient.readLine();
if (fromclient.equals("q") || fromclient.equals("Q")) {
connected.close();
break;
} else {
System.out.println("RECIEVED:" + fromclient);
}
}
}
}
}
The Client Code:
//TCPClient.java
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String argv[]) throws Exception {
String FromServer;
String ToServer;
Socket clientSocket = new Socket("localhost", 5000);
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
PrintWriter outToServer = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
while (true) {
FromServer = inFromServer.readLine();
if (FromServer.equals("q") || FromServer.equals("Q")) {
clientSocket.close();
break;
} else {
System.out.println("RECIEVED:" + FromServer);
System.out.println("SEND(Type Q or q to Quit):");
ToServer = inFromUser.readLine();
if (ToServer.equals("Q") || ToServer.equals("q")) {
outToServer.println(ToServer);
clientSocket.close();
break;
} else {
outToServer.println(ToServer);
}
}
}
}
}
This exception means that there is no service listening on the IP/port you are trying to connect to:
You are trying to connect to the wrong IP/Host or port.
You have not started your server.
Your server is not listening for connections.
On Windows servers, the listen backlog queue is full.
I would check:
Host name and port you're trying to connect to
The server side has managed to start listening correctly
There's no firewall blocking the connection
The simplest starting point is probably to try to connect manually from the client machine using telnet or Putty. If that succeeds, then the problem is in your client code. If it doesn't, you need to work out why it hasn't. Wireshark may help you on this front.
You have to connect your client socket to the remote ServerSocket. Instead of
Socket clientSocket = new Socket("localhost", 5000);
do
Socket clientSocket = new Socket(serverName, 5000);
The client must connect to serverName which should match the name or IP of the box on which your ServerSocket was instantiated (the name must be reachable from the client machine). BTW: It's not the name that is important, it's all about IP addresses...
I had the same problem, but running the Server before running the Client fixed it.
One point that I would like to add to the answers above is my experience-
"I hosted on my server on localhost and was trying to connect to it through an android emulator by specifying proper URL like http://localhost/my_api/login.php . And I was getting connection refused error"
Point to note - When I just went to browser on the PC and use the same URL (http://localhost/my_api/login.php) I was getting correct response
so the Problem in my case was the term localhost which I replaced with the IP for my server (as your server is hosted on your machine) which made it reachable from my emulator on the same PC.
To get IP for your local machine, you can use ipconfig command on cmd
you will get IPv4 something like 192.68.xx.yy
Voila ..that's your machine's IP where you have your server hosted.
use it then instead of localhost
http://192.168.72.66/my_api/login.php
Note - you won't be able to reach this private IP from any node outside this computer. (In case you need ,you can use Ngnix for that)
I had the same problem with Mqtt broker called vernemq.but solved it by adding the following.
$ sudo vmq-admin listener show
to show the list o allowed ips and ports for vernemq
$ sudo vmq-admin listener start port=1885 -a 0.0.0.0 --mountpoint /appname --nr_of_acceptors=10 --max_connections=20000
to add any ip and your new port. now u should be able to connect without any problem.
Hope it solves your problem.
Hope my experience may be useful to someone. I faced the problem with the same exception stack trace and I couldn't understand what the issue was. The Database server which I was trying to connect was running and the port was open and was accepting connections.
The issue was with internet connection. The internet connection that I was using was not allowed to connect to the corresponding server. When I changed the connection details, the issue got resolved.
In my case, I gave the socket the name of the server (in my case "raspberrypi"), and instead an IPv4 address made it, or to specify, IPv6 was broken (the name resolved to an IPv6)
In my case, I had to put a check mark near Expose daemon on tcp://localhost:2375 without TLS in docker setting (on the right side of the task bar, right click on docker, select setting)
i got this error because I closed ServerSocket inside a for loop that try to accept number of clients inside it (I did not finished accepting all clints)
so be careful where to close your Socket
I had same problem and the problem was that I was not closing socket object.After using socket.close(); problem solved.
This code works for me.
ClientDemo.java
public class ClientDemo {
public static void main(String[] args) throws UnknownHostException,
IOException {
Socket socket = new Socket("127.0.0.1", 55286);
OutputStreamWriter os = new OutputStreamWriter(socket.getOutputStream());
os.write("Santosh Karna");
os.flush();
socket.close();
}
}
and
ServerDemo.java
public class ServerDemo {
public static void main(String[] args) throws IOException {
System.out.println("server is started");
ServerSocket serverSocket= new ServerSocket(55286);
System.out.println("server is waiting");
Socket socket=serverSocket.accept();
System.out.println("Client connected");
BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str=reader.readLine();
System.out.println("Client data: "+str);
socket.close();
serverSocket.close();
}
}
I changed my DNS network and it fixed the problem
You probably didn't initialize the server or client is trying to connect to wrong ip/port.
Change local host to your ip address
localhost
//to you local ip
192.168.xxxx
I saw the same error message ""java.net.ConnectException: Connection refused" in SQuirreLSQL when it was trying to connect to a postgresql database through an ssh tunnel.
Example of opening tunel:
Example of error in Squirrel with Postgresql:
It was trying to connect to the wrong port. After entering the correct port, the process execution was successful.
See more options to fix this error at: https://stackoverflow.com/a/6876306/5857023
In my case, with server written in c# and client written in Java, I resolved it by specifying hostname as 'localhost' in the server, and '[::1]' in the client. I don't know why that is, but specifying 'localhost' in the client did not work.
Supposedly these are synonyms in many ways, but apparently, not not a 100% match. Hope it helps someone avoid a headache.
For those who are experiencing the same problem and use Spring framework, I would suggest to check an http connection provider configuration. I mean RestTemplate, WebClient, etc.
In my case there was a problem with configured RestTemplate (it's just an example):
public RestTemplate localRestTemplate() {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", <some port>));
SimpleClientHttpRequestFactory clientHttpReq = new SimpleClientHttpRequestFactory();
clientHttpReq.setProxy(proxy);
return new RestTemplate(clientHttpReq);
}
I just simplified configuration to:
public RestTemplate restTemplate() {
return new RestTemplate(new SimpleClientHttpRequestFactory());
}
And it started to work properly.
There is a service called MySQL80 that should be running to connect to the database
for windows you can access it by searching for services than look for MySQL80 service and make sure it is running
It could be that there is a previous instance of the client still running and listening on port 5000.
I will start by saying that I'm not absolutely a network expert.
I'm trying to create a UDP multicast socket system with four RaspBerry Pi model B.
Into each Rpi is running a listening script (I will call it "listen.py") socket client.
Case 1 - I'm perfectly able to send datagram if I run the socket server (I will call it "server.py") directly inside of the Rpi (by SSH, with my laptop as well).
I have:
-listen.py on boot of the Rpi (here I create a socket client);
-I run the server.py (the server.py is obviously into the Rpi)
In this case I receive answer from all 4 Rpi that joined the multicast group (224.1.1.1)
Case 2 - I created a socket server java and a socket client python in my laptop and everything works perfectly (same code, same multicast group, same multicast port).I tried also without multicast using just 'localhost' and everything works as well. With netstat I can see multicast group and port.
netstat -lu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 224.1.1.1:21581 *:* //MulticastGroupIp:Port
udp 0 0 192.168.1.103:ntp *:* //Static ip of one Rpi
udp 0 0 *:ntp *:*
My problem is that if I run the server.py from my laptop (no SSH) I have no answer from the listen.py, socket client, which is running into the Rpi. I absolutely need to send datagram from my laptop (I want a java class) to the 4 Rpi.
I have excluded the possibilities of bad code, wrong multicast ip group, wrong multicast port group. Firewall is off in my laptop and in the router as well.
The parameter net.ipv4.ip_forward on the Rpi is 1.
I know that UDP is unreliable but here I'm speaking about 100% of the datagram lost.
IGMP is enabled on my D-Link router.
I have the same problem with Ethernet and WiFi configuration.
I really need other ideas.....So I tried to write here.
Sorry, this is my first post and I'm newbie a bit of everything.
I will appreciate any suggestion.
Probably it's something stupid that I can't understand.
Maybe some problems with the routing table???? This is mine:
route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default D-Link.Home 0.0.0.0 UG 0 0 0 wlan0
192.168.1.0 * 255.255.255.0 U 0 0 0 wlan0
Thanks in advance
For me the code works well and the problem is not there but if can be useful to understand better the situation.....
Code of server.py (useless to say that I have python installed in my machine with Windows 7):
import socket
import sys
# import time
print 'message:'
n = sys.stdin.readline()
n = n.strip('\n')
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 21581
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.sendto(n, (MCAST_GRP, MCAST_PORT))
or with java (It's exactly what I want...a server socket java but at the moment it's not the priority):
public class PythonScriptScan {
private static int portMulticasting = 21581;
// private boolean broadcast = true;
private DatagramSocket socket;
private String groupMulticast = "224.1.1.1"; // group address
private int delay = 3000;
public PythonScriptScan() {
try {
socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
System.exit(1);
}
}
public void start(String agentName) {
try {
InetAddress group = InetAddress.getByName(groupMulticast);
#SuppressWarnings("resource")
MulticastSocket s = new MulticastSocket(portMulticasting);
s.joinGroup(group);
// while (broadcast) {
byte[] buf = new byte[10240];
buf = agentName.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, portMulticasting);
System.out.println(packet);
socket.send(packet);
// OK, I'm done talking - leave the group...
s.leaveGroup(group);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
System.exit(0);
}
// }
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
System.out.println("Insert Message");
#SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
String agentName = sc.nextLine();
PythonScriptScan agent = new PythonScriptScan();
agent.start(agentName);
}
and listen.py (It's running on boot in each Rpis, the configuration that I want is with Ethernet, each Rpis has a static ip and they are connected properly with my D-link router):
#!/usr/bin/python
import socket
import struct
import fcntl
import subprocess
import sys
import errno
import time
import os
# Create the socket
MCAST_GRP = "224.1.1.1"
MCAST_PORT = 21581
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
except socket.error, msg:
print 'Could not create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind to the server address
# sock.bind(('', MCAST_PORT))
sock.bind((MCAST_GRP, MCAST_PORT))
# Tell the operating system to add the socket to the multicast group on all interfaces
mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# Receive loop
try:
while True:
print >>sys.stderr, '\nWAITING TO RECEIVE MESSAGE'
d = sock.recvfrom(10240)
data = d[0]
addr = d[1]
print data.strip(), addr
finally:
print >>sys.stderr, 'closing socket'
sock.close()
I have a local network with DHCP and a few PCs. One of these should be my Server and get automatically connected to all others (clients). My idea was this:
First, I create a server on every client (CServer) that is listening for a client programm from the server (SClient). When the SClient connects to a CServer, the SClient sends the CServer his IP, so he knows there will be the server on this IP. Then after trying all IPs in his IP range (e.g. 192.168.1.xxx), he starts the real server and all the clients connect to the known server IP.
But when I try the following, the SClient just freezes at the first IP, when trying to connect to 192.168.1.0. How can i define a timeout or something similar that lets the SClient drop the unsuccessful connection and going on with 192.168.1.1?
import java.lang.*;
import java.io.*;
import java.net.*;
class SClient {
public SClient() {
for(int i = 120; i < 125; i++){
try{
InetAddress addr = InetAddress.getLocalHost();
String addrs = addr+"";
String ip = addrs.substring(addrs.indexOf("/")+1);
Socket s1 = new Socket("192.168.1." + i, 1254);
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream (s1out);
dos.writeUTF(ip);
dos.close();
s1out.close();
s1.close();
}catch(IOException e){}
}
}
}
and
import java.lang.*;
import java.io.*;
import java.net.*;
class CServer {
public CServer() throws IOException{
ServerSocket s = new ServerSocket(1254);
while(true){
Socket s1=s.accept();
InputStream s1In = s1.getInputStream();
DataInputStream dis = new DataInputStream(s1In);
String st = new String (dis.readUTF());
System.out.println(st);
dis.close();
s1In.close();
s1.close();
}
}
}
I've found a solution for my problem. It was just initializing the Socket not with
Socket s1 = new Socket("192.168.1." + i, 1254);
but with
Socket s1 = new Socket();
s1.setSoTimeout(200);
s1.connect(new InetSocketAddress("192.168.1." + i, 1254), 200);
Thanks anyway!
It's much easier to do this with UDP. The general logic would be:
Identify a well known port for 'discovery'
Any machine that starts up sends out a 'Query Master Server' message
If a response is not received to that message within a time frame
you define, then the machine that sent it automatically designates
itself as being the server.
Henceforth, any machine that sends out a 'Query Master Server'
message will get a response back from the master, with its IP
address and a 'communication port'
Connect from the new machine to the server on the communication port
and start sending messages.
You might run into situations where more than one server thinks it is the master in this scenario, and then you would need a conflict resolution process, but the outline should give you a general idea of a process that will work for you.