I have kinda figured out how sockets work but I seem to have run into another wall. I'm supposed to somehow use the socket to transfer the data, but how? when I try it gives me a SocketException bind, saying it's already in use. I used it originally to connect it to a Directory, where I will gather other nodes and then if one doesn't have the data, it will ask for it from the other nodes.
class Download extends Thread {
CloudByte[] list = new CloudByte[1000000];
#Override
public void run() {
try {
var nodes = ConnectingDirectory.getNodes();
for (Nodes node : nodes) {
if ((node.getHostPort() == ConnectingDirectory.getHostIP())) {
downloadFile(node.getHostPort());
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
try {
fileWriting(getFile().getName(), list);
} catch (IOException e) {
e.printStackTrace();
}
}
public synchronized void downloadFile(int port) throws IOException, ClassNotFoundException {
while (true) {
ServerSocket ss = ConnectingDirectory.getServerSocket();
Socket socket = ss.accept();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
for (int j = 0; j <= 9999; j += 1) {
byte[] bit = (byte[]) ois.readObject();
for (int i = 0; i < bit.length; i++) {
list[i + j * 100] = new CloudByte(bit[i]);
}
}
System.out.println("Download Completed");
}
}
This is the function, I'm using to Download the date from the InputStream, the problem I'm having is that it's not downloading unless I restart the other Node. Is there a way to avoid having to do that? I really am at a loss.
Note; the for is because I need to transfer 1000000 bytes, in packets of 100 bytes.
The sending the data is:
class Upload extends Thread {
#Override
public void run() {
if (getFile().exists()) {
var nodes = ConnectingDirectory.getNodes();
for (Nodes node : nodes) {
if (node.getHostPort() == ConnectingDirectory.getHostIP()) {
try {
uploadFile(node.getHostPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
new Download().start();
}
}
public static void uploadFile(int hostPort) throws IOException {
Socket socket = new Socket("localhost", hostPort);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ByteBlockRequest bbr = new ByteBlockRequest(getStoredData());
for (int j = 0; j <= 9999; j += 1) {
objectOutputStream.writeObject(bbr.blocksToSend(j));
}
objectOutputStream.flush();
System.out.println("Uploaded all the Data!");
}
Creating the server socket:
public ConnectingDirectory(String hostName, int hostIP, int directoryIP) throws IOException {
this.hostName = hostName;
this.directoryIP = directoryIP;
ConnectingDirectory.hostIP = hostIP;
this.address = InetAddress.getByName(hostName);
socket = new Socket(address, directoryIP);
serverSocket = new ServerSocket(hostIP);
signUp();
askConnectedNodes();
}
Related
I'm trying to write a simple client/server application. I have a data on a client's side, that turns into an integer array and transfers to server. The server makes the calcutaions and returns them to client. But my program falls with this exception.
Sorry for long text, I'm just studying and really need your help.
public class Client {
private static Socket clientSocket;
private static ObjectInputStream in;
private static ObjectOutputStream out;
private static int[] parsedValue;
public Client(String input) {
try {
parsedValue = Arrays.stream(input.split(",")).mapToInt(Integer::parseInt).toArray();
} catch (Exception e) {
e.printStackTrace();
}
}
public Client(int[] input) {
parsedValue = input;
}
public Client(List<Integer> input) {
try {
parsedValue = input.stream().mapToInt(d->d).toArray();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
try {
clientSocket = new Socket("localhost", 4004);
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
String clientTestString = "440,5,16";
Client stringClient = new Client(clientTestString);
out.writeObject(stringClient.parsedValue);
out.flush();
System.out.println(in.readObject());
int[] clientIntsTest = {39, 10, 5};
Client arrayClient = new Client(clientIntsTest);
out.writeObject(arrayClient.parsedValue);
out.flush();
System.out.println(in.readObject());
List<Integer> clientsTestList = Arrays.asList(781, 9, 7);
Client listClient = new Client(clientsTestList);
out.writeObject(listClient.parsedValue);
out.flush();
System.out.println(in.readObject());
} finally {
System.out.println("Client was closed");
clientSocket.close();
in.close();
out.close();
}
} catch (IOException | ClassNotFoundException e) {
System.err.println(e);
}
}
}
public class Server {
private static Socket clientSocket;
private static ServerSocket server;
private static ObjectInputStream in;
private static ObjectOutputStream out;
private static int[] parsedValue;
public String getResult() {
return calculation(parsedValue);
}
public String calculation(int[] parsedValue) {
parsedValue[0] = toDecimal(parsedValue[0], parsedValue[1]);
String answer = "";
int temp = 0;
String digits = new String("ABCDEF");
while (parsedValue[0] > 0) {
temp = parsedValue[0] % parsedValue[2];
if (temp < 10) {
answer = temp + answer;
} else {
answer = digits.charAt(temp - 10) + answer;
}
parsedValue[0] /= parsedValue[2];
}
return answer;
}
public int toDecimal(int value, int baseNotation) {
int i = 0;
int decimalNumber = 0;
if (value > 0) {
while (value != 0) {
decimalNumber += (value % 10) * Math.pow(baseNotation, i);
value /= 10;
i++;
}
}
return decimalNumber;
}
public static void main(String[] args) {
try {
try {
server = new ServerSocket(4004);
System.out.println("Server runs");
clientSocket = server.accept();
try {
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
parsedValue = (int[]) in.readObject();
System.out.println(parsedValue);
Server examp = new Server();
String answer = examp.getResult();
System.out.println(answer);
out.writeObject(answer);
out.flush();
} finally {
clientSocket.close();
in.close();
out.close();
}
} finally {
System.out.println("Server closed");
server.close();
}
} catch (IOException | ClassNotFoundException e) {
System.err.println(e);
}
}
}
In this two lines
Server examp = new Server();
String answer = examp.getResult();
you cretat a new object which overriddes the field private static ServerSocket server;
A better solution is to put the logic from your main() into a seperate method like run(), instantiate in main() a new object of server and call the run() on it. Dont't forget to make all fields as instance members by removing the static keyword.
public static void main(String[] args) {
Server examp = new Server();
examp.run();
}
public void run() {
try {
try {
server = new ServerSocket(4004);
System.out.println("Server runs");
clientSocket = server.accept();
try {
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
parsedValue = (int[]) in.readObject();
System.out.println(parsedValue);
String answer = getResult();
System.out.println(answer);
out.writeObject(answer);
out.flush();
} finally {
clientSocket.close();
in.close();
out.close();
}
} finally {
System.out.println("Server closed");
server.close();
}
} catch (IOException | ClassNotFoundException e) {
System.err.println(e);
}
}
By the way: You should always use this patern to get out of the 'static-trap'. So I suggest you refactor your Client calss too.
I am trying to create for a university project a server / slave / client project.
The server should open 2 ports, one port will be for the connection of the slave and another port for the client.
I have setup 2 threads 1 for the client and another for the slave. The client should sent random numbers to server and server should forward randomly those numbers to slave instances. The slave should check if the current number exist on their list and if it's not available to store it, otherwise they should sent a message to server that the number already exist.
Then I created the client thread which consist of 2 threads, one for sending the numbers to server and another thread to read messages coming from the server.
There is something wrong with the code of the PrintWriter, I cannot make it to send the numbers to server when the code is inside the thread. If I move the code on the main and cancel the thread the messages are being sent without any issue.
What could be the issue for this?
Below is the current code from server (master) and the client.
public class Client {
private static final int NUMBERS = 50;
private static final int AMPLITUDE = 100;
private static int masterPort;
public Client(int port) {
this.masterPort = port;
}
public static void main(String[] args) throws IOException{
String serverHostname = "127.0.0.1";
System.out.println("Αναμονή για σύνδεση στον σέρβερ " + serverHostname + " στην πόρτα 30091.");
Socket echoSocket = null;
BufferedReader in = null;
try {
echoSocket = new Socket(serverHostname, 18889);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Δεν μπορεί να πραγματοποιηθεί σύνδεση με τον σέρβερ: " + serverHostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + serverHostname);
System.exit(1);
}
ClientOut clientOut = new ClientOut(echoSocket);
clientOut.start();
ClientIn clientIn = new ClientIn(in);
clientIn.start();
in.close();
echoSocket.close();
}
public static class ClientOut extends Thread {
private PrintWriter out;
public ClientOut(Socket echoSocket) throws IOException {
this.out = new PrintWriter(echoSocket.getOutputStream(), true);
}
#Override
public void run() {
System.out.println("Ο client συνδέθηκε!");
Random rnd = new Random();
try {
for (int i=0; i<NUMBERS; i++) {
int num = rnd.nextInt(AMPLITUDE);
System.out.println(num);
out.println(num);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
out.close();
}
}
public static class ClientIn extends Thread {
private BufferedReader in;
public ClientIn(BufferedReader in) {
this.in = in;
}
#Override
public void run() {
}
}
}
public class Master {
private int slavePort;
private int clientPort;
private SlaveThread slaveThread;
private ClientThread clientThread;
private boolean running = false;
public static int slaveConnected; // Slave connection counter
public Master(int slavePort, int clientPort) {
this.slavePort = slavePort;
this.clientPort = clientPort;
this.slaveConnected = 0;
public void startServer() {
try {
this.slaveThread = new SlaveThread(slavePort);
this.clientThread = new ClientThread(clientPort);
System.out.println( "Αναμονή για σύνδεση client / slave" );
slaveThread.start();
clientThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopServer() {
running = false;
this.slaveThread.interrupt();
this.clientThread.interrupt();
}
class SlaveThread extends Thread {
private ServerSocket slaveSocket;
SlaveThread(int slavePort) throws IOException {
this.slaveSocket = new ServerSocket(slavePort);
}
#Override
public void run() {
running = true;
while (running) {
try {
// Call accept() to receive the next connection
Socket slSocket = slaveSocket.accept();
System.out.println("Δημιουργήθηκε μια νέα σύνδεση Slave");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ClientThread extends Thread {
private ServerSocket clientSocket;
ClientThread(int clientPort) throws IOException {
this.clientSocket = new ServerSocket(clientPort);
}
#Override
public void run() {
running = true;
while (running) {
try {
Socket clSocket = clientSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clSocket.getInputStream()));
System.out.println("Δημιουργήθηκε μια νέα σύνδεση Client");
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Client: " + inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Master server = new Master( 30091, 18889);
server.startServer();
// Automatically shutdown in 1 minute
try {
Thread.sleep( 60000 );
} catch(Exception e) {
e.printStackTrace();
}
server.stopServer();
}
I found the solution.
The Socket should be created on the Client Thread constructor and not to be passed as reference.
So the client should be
public class Client {
private static final int NUMBERS = 50;
private static final int AMPLITUDE = 100;
private static int masterPort;
public Client(int port) {
this.masterPort = port;
}
public static void main(String[] args) throws IOException{
String serverHostname = "127.0.0.1"; //Ορίζουμε την διεύθυνση που είναι ο σέρβερ
System.out.println("Αναμονή για σύνδεση στον σέρβερ " + serverHostname + " στην πόρτα 30091.");
ClientOut clientOut = new ClientOut(serverHostname);
clientOut.start();
ClientIn clientIn = new ClientIn(serverHostname);
clientIn.start();
}
public static class ClientOut extends Thread {
private Socket echoSocket;
private PrintWriter writer;
ClientOut(String serverHostname) throws IOException {
this.echoSocket = new Socket(serverHostname, 18889);
this.writer = new PrintWriter(echoSocket.getOutputStream(), true);;
}
#Override
public void run() {
System.out.println("Ο client συνδέθηκε!");
Random rnd = new Random();
try {
for (int i=0; i<NUMBERS; i++) {
int num = rnd.nextInt(AMPLITUDE);
System.out.println(num);
writer.println(num);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
writer.close();
}
}
First some Information regarding my Setup.
I have a S8 Cellphone, where i run this App, based upon the AR-Devkit demo from Google.
public void closeSocket(DatagramSocket socket) {
if (socket != null && socket.isConnected() ) {
while (!socket.isConnected()) {
socket.disconnect();
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
if (socket != null && !socket.isClosed()) {
socket.close();
while (!socket.isClosed()) {
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
}
public DatagramSocket createSocket(InetAddress ipAddress, int port) {
try {
DatagramSocket socket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress(ipAddress, port);
socket.setReuseAddress(true);
socket.bind(address);
return socket;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public DatagramSocket getBroadcastListenerSocket() throws IOException {
InetSocketAddress anyAdress = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 9000);
DatagramSocket socket = new DatagramSocket(null);
socket.setSoTimeout(30);
socket.setReuseAddress(true);
socket.bind(anyAdress);
return socket;
}
public DatagramSocket getBroadcastSenderSocket(DatagramSocket oldSocket) {
DatagramSocket socket = null;
try {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
socket = getSocket(oldSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
socket.setBroadcast(true);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
public DatagramSocket getSocket(DatagramSocket oldSocket, InetAddress ipAddress, int port, InetAddress targetAddress) {
if (oldSocket != null ) {
closeSocket(oldSocket);
}
DatagramSocket socket = null;
try {
socket = createSocket(ipAddress, port);
socket.setBroadcast(false);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
if (targetAddress != null)
socket.connect(targetAddress, port);
} catch (SocketException e) {
e.printStackTrace();
}
return socket;
}
public class DatagramReciever extends Thread {
private String datagramToSend = "";
private boolean newDatagramToSend = false;
private DatagramPacket snd_packet;
DatagramSocket senderSocket = null;
DatagramSocket listenerSocket = null;
private DatagramSocket broadCastListenerSocket;
//Buffer gettters and setters
private int writeBuffer = 0;
private SpringAR.comStates oldState;
int getReadBuffer() {
if (writeBuffer == 1) return 0;
return 1;
}
void switchBuffer() {
recieveByteIndex = 0;
writeBuffer = getReadBuffer();
}
public String dbg_message = "";
//Management Communication Headers
public void kill() {
closeSocket(senderSocket);
closeSocket(listenerSocket);
closeSocket(broadCastListenerSocket);
}
public void run() {
try {
initializeBroadcastConnection();
while (true) {
//Recieving Datagramm
DatagramPacket rcv_packet = new DatagramPacket(rcv_message[writeBuffer], rcv_message[writeBuffer].length);
boolean NewMessageArrived = true;
try {
listenerSocket.receive(rcv_packet);
} catch (SocketTimeoutException e) {
NewMessageArrived = false;
}
//Watchdog
handleWatchDogTimer(State);
//TODO Delete String conversion
if (NewMessageArrived) {
dbg_message = new String(rcv_message[writeBuffer], 0, rcv_packet.getLength(), "US-ASCII");
Log.d(SpringAR.dataDebugLogPrefix, "" + rcv_packet.getAddress().getHostAddress() + ": " + dbg_message.trim() + " of " + rcv_packet.getLength() + "length ");
}
if (validatePackageSender(rcv_packet)) {
connectionStateMachine(rcv_message, rcv_packet);
}
//Sending Datagram
if (newDatagramToSend && hostIpAddress != null) {
//Log.d(SpringAR.protocollDebugLogPrefix, "Server sending: " + datagramToSend);
byte[] snd_message = datagramToSend.getBytes();
try {
snd_packet = packSendPackageByState(snd_message);
assert (snd_packet != null);
senderSocket.send(snd_packet);
newDatagramToSend = false;
} catch (IOException e1) {
e1.printStackTrace();
//causes Caused by: android.system.ErrnoException: sendto failed: EINVAL (Invalid argument)
Log.e(SpringAR.protocollDebugLogPrefix, "Server Error in State: " + State.name());
break;
}
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
private void initializeBroadcastConnection() throws IOException {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
senderSocket = getSocket(null, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
broadCastListenerSocket = getBroadcastListenerSocket();
listenerSocket = broadCastListenerSocket;
Log.d(SpringAR.protocollDebugLogPrefix, "initializeBroadcastConnection completed");
}
// handles management traffic like configurstion files
private void connectionStateMachine(byte[][] payload, DatagramPacket rcv_packet) throws IOException {
//Reset triggered by Host
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveResetHeaderByte) != SpringAR.STRING_NOT_FOUND) {
State = SpringAR.comStates.STATE_resetCommunication;
}
Log.d(SpringAR.protocollDebugLogPrefix, "ConnectionStateMachine: " + State.name());
switch (State) {
case STATE_resetCommunication: {
messageCounter = 0;
listenerSocket = broadCastListenerSocket;
hostIpAddress = comonUtils.getBroadcastAddress(context);
senderSocket = getBroadcastSenderSocket(senderSocket);
setSendToSpringMessage(SpringAR.sendResetHeader);
State = SpringAR.comStates.STATE_broadCastHeader;
return;
}
case STATE_broadCastHeader: {
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveHostReplyHeaderByte) != SpringAR.STRING_NOT_FOUND) {
Log.d(SpringAR.protocollDebugLogPrefix, " Host Reply Header recieved");
//Extract the hostIp
String hostIpAdressAsString = new String(payload[writeBuffer]);
hostIpAdressAsString = hostIpAdressAsString.replace(SpringAR.recieveHostReplyHeader, "").trim();
Log.d(SpringAR.dataDebugLogPrefix, hostIpAdressAsString);
hostIpAddress = InetAddress.getByName(hostIpAdressAsString);
//Set Connection from broadcast to target
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
Log.d(SpringAR.protocollDebugLogPrefix, " New Device Adress " + ARDeviceAddress);
senderSocket = getSocket(senderSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, hostIpAddress);
listenerSocket = senderSocket;
State = SpringAR.comStates.STATE_sendCFG;
return;
}
setSendToSpringMessage(SpringAR.sendBroadcasteHeader);
delayByMs(SpringAR.TIME_OUT_IN_BROADCAST);
return;
}
case STATE_sendCFG: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveCFGHeaderByte )) {
State = SpringAR.comStates.STATE_sendRecieveData;
return;
}
setSendToSpringMessage(SpringAR.formConfigurationMessage());
return;
}
case STATE_sendRecieveData: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveDataHeaderByte)) {
writeRecievedDataToBuffer(payload[writeBuffer], rcv_packet.getLength());
}
break;
}
default:
Log.d(SpringAR.protocollDebugLogPrefix, "Connection State Machine invalid state");
}
}
https://github.com/PicassoCT/arcore-android-sdk/blob/6c9b48a3d520e039cd48bc2af7354ccdec857736/arcore-android-sdk/samples/hello_ar/app/src/main/java/com/google/ar/core/examples/app/common/tcpClient/Server.java
All the testing is happening in a home-WiFi Setup, where the desktop with the host-application is directly attached to the WiFi-Router.
What is working thus far:
The device can broadcast its presence.
The host can broadcast its configuration.
The Device can not communicate from IP to IP on the host. Both sides have fixed IP set.
I can communicate with the App PacketSender with the host-Application, and ruled a failure on its part out.
I also built a smaller debug-loop, to only send udp-packets back and forth, which also worked.
Thank you for your time
Change this line:
socket.setSoTimeout(30);
to
socket.setSoTimeout(1000);
You've got a fairly complex state machine going here, and it's difficult to discern what is happening without having logs to look at. I would summarize your state machine like this:
Broadcast a configuration message
Spend 30ms listening for a response
If no response is received, block for SpringAR.TIME_OF_FRAME_IN_MS (not included in your code; I assume it is 1000ms), and loop back to #1
If a response was received, send a reply directly to the peer, and go to #2
#4 is the step that isn't happening. The likely reason (based on the Wireshark dump) is that it's taking 68ms for ARDevice's response to reach "Host". You only gave it 30ms. There could be a number of reasons it's taking so long, but that's beyond the scope of your question.
I'm writing test for my chat-client system which works with sockets and 1 server. I have created 3 sockets(each one in thread representing client) which choose chat-room( "USA room") and all send 1 message, here is what I do-start the server, wait all clients to come in the room, each send a message, then read all messages from each socket,shutdown server, however while reading some socket's messages the test freezes. This freezing is caused by this line: String line = reader.readLine();. Some sockets receive the right amount of messages (which is 5), others just freeze with messages less than 5. I can't figure why the socket freeze.
public class ChatTest {
final int NUMBER_OF_SOCKETS = 3;
Server server = new Server();
Map<String, Socket> mapSockets = new ConcurrentSkipListMap<>();
List<String> socketMessages = new CopyOnWriteArrayList<>();
List<Thread> allThreads = new CopyOnWriteArrayList<>();
List<Socket> allsockets = new CopyOnWriteArrayList<>();
Set<Set<String>> allSets = new HashSet<>();
Map<Thread, Socket> mapThreadSocket = new ConcurrentHashMap<>();
private final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_SOCKETS);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
server.start();
}
});
#BeforeSuite(alwaysRun = true)
public void startServer() {
t.start();
}
#AfterSuite(alwaysRun = true)
public void stopServer() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
server.stop();
}
Thread t2 = new Thread() {
#Override
public void run() {
try {
final List<String> linesFromFile = ChatSystemUtils.readFromFile(ClientTestDataConstants.TestDataFile.toString(), 50);
System.out.println("all client threads have entered room called USA room ");
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
final PrintWriter stream = new PrintWriter(allsockets.get(i).getOutputStream(), true);
mapSockets.put(linesFromFile.get(i), allsockets.get(i));
stream.println(linesFromFile.get(i));
socketMessages.add(i, linesFromFile.get(i));
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(allsockets.get(i).getInputStream()));
System.out.println("AT NEW USER");
Set<String> userMessages = new HashSet<>();
for (int j = 0; j < 5; j++) {
String line = reader.readLine();
System.out.println(line);
if (j > NUMBER_OF_SOCKETS) {
String msg = line.substring(9, line.length());
userMessages.add(msg);
}
}
userMessages.add(socketMessages.get(i));
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
#Test
public void testMessagesReceived() throws IOException {
List<Thread> threadList = new LinkedList<>();
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e1) {
e1.printStackTrace();
}
try {
Socket socket = new Socket("127.0.0.1", 3000);
allsockets.add(socket);
final PrintWriter stream = new PrintWriter(socket.getOutputStream(), true);
stream.println("USA room");
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(r);
threadList.add(t);
}
for (int i = 0; i < threadList.size(); i++) {
threadList.get(i).start();
}
for (int i = 0; i < threadList.size(); i++) {
try {
threadList.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("most of the times we don't get here ");
}
}
Server class :
public final class Server {
public static boolean stopServerCalled;
private final int port;
private final String host;
private final Map<String, ChatRoom> mapRooms = ChatServerUtils.getChatRooms();
private final AtomicInteger clientID = new AtomicInteger(1);
private ServerSocket serverSocket;
private List<IClient> clientsPickingRoom;
private final ExecutorService executorService = Executors.newCachedThreadPool();
public Server() {
final Properties prop = new Properties();
try (final InputStream inputStream = getClass()
.getResourceAsStream("/com/egt/chat/server/ChatServerConfig.properties")) {// read from a file of
// properties
prop.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
this.port = Integer.parseInt(prop.getProperty("port"));
this.host = prop.getProperty("host");
this.clientsPickingRoom = new CopyOnWriteArrayList<>();
}
public void start() {
try {
final InetAddress address = InetAddress.getByName(host);
serverSocket = new ServerSocket(port, 50, address);
System.out.println("Listening on socket : " + serverSocket);
while (!Thread.currentThread().isInterrupted()) {
final Socket newSocket = serverSocket.accept();
System.out.println("Connection established with: " + newSocket);
final ClientContainer newClient = new ClientContainer(clientID.get(), newSocket);
executorService.execute(new ClientContainerRunnable(newClient, this));
clientID.incrementAndGet();
clientsPickingRoom.add(newClient);
}
} catch (IOException e) {
System.out.println("Server stopped!");
}
}
}
PrintWriter stream = new PrintWriter(allsockets.get(i).getOutputStream(), true);
stream.println(linesFromFile.get(i));
Isn't writing to this client socket, it's sending a message out to the server it's connected to. Where is the server writing the 5 lines to each client socket, which you read here:
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(allsockets.get(i).getInputStream()));
for (int j = 0; j < 5; j++) {
String line = reader.readLine();
System.out.println(line);
// ...
It may be best if you dump all your code, then I could actually help. As it is, you aren't really helping me help you.
I'm working on a client-server application with two modules:
1). Registry: All servers in the network register their IP and port they are listening to with the registry.
2). Messaging node: These are also servers, which communicate with each other in a round of messages, once they receive the command from the registry. A messaging node will only send messages to 1 node at a time, but may receive from multiple nodes.
The registry sends a list of available (registered) nodes to all other servers, and upon receiving this list, the nodes start exchanging messages with each other.
I was able to get the registry part working, and the nodes are able to register themselves. Also, the nodes successfully receive the nodes list from the registry and able to start exchanging messages. How ever, the messaging nodes are not able to receive all the messages being sent.
Here's the messaging node part:
public class MessagingNode {
// Constructor
public MessagingNode(String registryHost, int registryPort) {
try {
registryHostname = InetAddress.getByName(registryHost).getHostAddress();
} catch (Exception e) {
System.out.println("Can't resolve Registry hostname!");
}
registryPortNumber = registryPort;
// Start the node server
try {
nodeServerSocket = new ServerSocket(0);
}
catch (Exception e) {
System.out.println("Can't start node server!");
}
// Store the MessagingNode server port and IP address
try {
nodeIpAddress = InetAddress.getLocalHost().getHostAddress();
} catch(Exception e) {
System.out.println("Can't get localhost");
}
nodePortNumber = nodeServerSocket.getLocalPort();
//System.out.println("Node Port:"+nodePortNumber);
// Initialize trackers
sendTracker = 0;
receiveTracker = 0;
sendSummation = 0;
receiveSummation = 0;
sending = false;
}
// Start the NodeServer to listen for other nodes
public void startNodeServer() {
if(!isRunning) {
isRunning = true;
consoleListener();
while(MessagingNode.this.isRunning) {
Socket clientSocket = null;
try {
clientSocket = nodeServerSocket.accept();
openClient(clientSocket);
}
catch(IOException e) {
e.printStackTrace();
}
}
}
}
// Messaging nodes receiving
public void openClient(final Socket socket) {
Thread clientThread = new Thread() {
public void run() {
int count = 0;
try {
byte[] messagePayload = new byte[64];
InputStream in = socket.getInputStream();
DataInputStream din = new DataInputStream(in);
//BufferedReader br = new BufferedReader(new InputStreamReader(in));
while(din.read(messagePayload) > -1) {
//count++;
int type = InterpretMessage.getMessageType(messagePayload);
if(type == MessageTypes.MESSAGING_NODES_LIST) {
trimNodeList(messagePayload);
System.out.println("Node list Received!");
dataThread();
}
else {
handleIncomingPayload(messagePayload);
}
}
//System.out.println("Input connection closed after :" + count);
//System.out.println("Listener Closed!");
//in.close();
//socket.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
};
clientThread.start();
try {
clientThread.join();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void dataThread() {
Thread t = new Thread() {
public void run() {
sendData();
}
};
t.start();
try {
t.join();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void sendData() {
// pick a node
int size = messagingNodesList.size();
int index = (int)(Math.random() * size);
//System.out.println("Node being contacted:" + messagingNodesList.get(index));
String details = messagingNodesList.get(index);
String[] str = details.split(" ");
try {
Socket socket = new Socket(str[0], Integer.parseInt(str[1]));
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
for(int i= 0; i < 5; i++) {
CommMessage outgoing = new CommMessage();
byte[] msg = outgoing.marshall();
out.write(msg, 0, msg.length);
System.out.println("Sending number:" + outgoing.number);
out.flush();
}
out.close();
//closeConnection = true;
}
catch(IOException e) {
e.printStackTrace();
}
}
// Remove Node's information
public void trimNodeList(byte[] incoming) {
// Removes the current node's information from the list recieved from registry
}
// Update trackers
public void handleIncomingPayload(byte[] payload) {
CommMessage msg = new CommMessage(payload);
msg.unmarshall();
System.out.println("Receiving Number:"+msg.number);
//synchronized(this) {
receiveSummation += msg.number;
receiveTracker += 1;
//}
}
// Console Listener
public void consoleListener() {
Thread listener = new Thread() {
public void run() {
// listen for keyboard instructions
}
};
listener.start();
}
public static void main(String[] args) {
MessagingNode node = new MessagingNode(args[0], Integer.parseInt(args[1]));
node.connectRegistry();
node.startNodeServer();
//node.deregisterNode();
//node.deregisterNode();
//node.sendBurst();
// Launch the console Listener Thread
// Initiate rounds of messaging
}
}
The problem is somewhere in the receiving portion I'm assuming. I tried using using synchronized on the sendData method as someone pointed out it could be a concurrency issue but it didn't help. I'm still not able to receive all messages. Any insights will be really helpful.
Thanks.