I have an error when a client closes the connection from the socket. What is supposed to happen is that the user closes their client, the server then receives this and should decrement the users who are connected which is stored in a relative integer value. However I receive an error relating to the for loop on the remove a user function.
public synchronized void removeUsers(Socket client,int clientUser)
{
int index=0;
for (ClientHandler newHandler:userList)
{
if(newHandler.getUserId() == clientUser)
{
try
{
client.close();
Thread.currentThread().isInterrupted();
userList.remove(index);
}
catch (IOException e)
{
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
index++;
}
}
Client handler run:
public void run()
{
String message;
message = input.nextLine(); //Note method!
getMessage(message);
System.out.println(message.substring(0, count+1)+"-"+message.substring(count+1));
while (!message.substring(0, count+1).equals("***CLOSE***"))
{
if(message.equals(user.getItemName(1)+"$status$")|| //checks for status of Ball
message.equals(user.getItemName(2)+"$status$"))
{
if (user.BidItem(user.getItemName(1)))
{
System.out.println("Top bid for " + //posts for server
message.substring(0, count+1) + " is: "
+ user.getTopBid(message.substring(0, count+1)));
output.println("Top bid for " + //posts for client
message.substring(0, count+1) + " is: "
+ user.getTopBid(message.substring(0, count+1))
+ " by User" +
user.getTopBidder(message.substring(0, count+1)));
}
else
{
System.out.println("-1");
output.println("-1");
}
}
else
{
if(user.BidItem(message.substring(count+2))) //same but now for Plate
{
if(user.isGrtrThanTopBid(message.substring(count+2),
Double.parseDouble(message.substring(0, count+1))))
{
user.setTopBid(message.substring(count+2),
Double.parseDouble(message.substring(0, count+1)), clientUser);
System.out.println("Bid Accepted for " + message.substring(count+2));
output.println("Bid Accepted for " + message.substring(count+2));
}
else
{
System.out.println("Low bid for " + message.substring(count+2));
output.println("Low bid for " + message.substring(count+2));
}
}
else
{
System.out.println("Late bid for " + message.substring(count+2));
output.println("Late bid for " + message.substring(count+2));
}
}
message = input.nextLine();
count = 0;
getMessage(message);
}
output.println(" messages received.");
System.out.println("\n* Closing connection... *");
user.removeUsers(client,clientUser);
}
The full error is here:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at Users.removeUsers(AuctionServer.java:211) //Relates to top of for loop
at ClientHandler.run(AuctionServer.java:435)
You can't remove objects from lists when you iterates on them.
Try this.
Instead use a queue.
Queue queue = new LinkedList<Client>();
int index=0;
for (ClientHandler newHandler:userList)
{
if(newHandler.getUserId() == clientUser)
{
try
{
client.close();
Thread.currentThread().isInterrupted();
queue.add(userList.get(index));
}
catch (IOException e)
{
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
index++;
}
while(!queue.isEmpty()) {
userList.remove(queue.remove());
}
Related
I am making a multicast messenger for part of my masters degree. I have previously successfully made this exact same implementation on desktop Java and had no issues what so ever. HOWEVER, when I run the code from Android problems occur. I can send to the multicast group just fine, but receiving does not work.
The output simply stops in the console after "2".
The application just stops giving me feedback on the line that is socket.receive()I am getting no exceptions either.
Below I have attached the class that I am using to receive the messages.
For the full android implementation I have the dropbox link available at: https://www.dropbox.com/s/vuoifbxqk01c079/MyApplication.zip?dl=0
It is pretty rough, but it does successfully send, just not receive.
public class EMMS extends Thread{
MulticastSocket socket;
InetAddress ip;
byte [ ] buffer;
int usedPort;
public boolean isSending;
private MainActivity view;
public EMMS(MainActivity view, int port, String ipAddress){
try {
// Create Multicast socket
socket = new MulticastSocket(port);
usedPort = port;
// Set address to join
ip = InetAddress.getByName(ipAddress);
// join group
socket.joinGroup(ip);
System.out.println("Group Joined! ");
// create buffer
buffer = new byte[512];
isSending = false;
this.view = view;
}//end of try
catch (SocketException se){
System.out.println("Socket Exception : " + se); }
catch (IOException e) { System.out.println("Exception : " + e); }
}
public void run(){
try {
System.out.println("Incoming Message! ");
while (isSending == false) {
// Create and receive packet
System.out.println("1");
DatagramPacket dp = new DatagramPacket(buffer, buffer.length,ip, usedPort);
System.out.println("2");
socket.receive(dp);
System.out.println("3");
String str = new String(dp.getData());
System.out.println("4");
String ipAddress = dp.getAddress().getHostAddress();
System.out.println("5");
// Create string array of components
String[] data = str.split("##");
String senderName= data[2];
String sourceIP= ipAddress;
String typeOfEmergency=data[3];
String condition=data[0];
String instruction=data[1];
System.out.println("Incoming Message! ");
System.out.println(
"Sender: " + senderName + "\n" +
"Source IP: " + sourceIP + "\n" +
"Emergency Type: " + typeOfEmergency + "\n" +
"Condition: " + condition + "\n" +
"Instruction: " + instruction
);
// Create popup window
AlertDialog alertDialog = new AlertDialog.Builder(view).create(); //Read Update
alertDialog.setTitle("ALERT");
alertDialog.setMessage(
"Sender: " + senderName + "\n" +
"Source IP: " + sourceIP + "\n" +
"Emergency Type: " + typeOfEmergency + "\n" +
"Condition: " + condition + "\n" +
"Instruction: " + instruction
);
alertDialog.show(); //<-- See This!
}
}//end of try
catch (SocketException se){
System.out.println("Socket Exception : " + se); }
catch (IOException e) { System.out.println("Exception : " + e); }
}
public void disconnect() throws IOException{
socket.leaveGroup(ip);
}
It works upto sock.receive(incoming); On my browser under applet.
After sock.receive(incoming); This line it is stuck. Nothing is display.
Or No Error or exception is throw even it goes away from this line.
Please Help me. Thank you in advance :)
sorry for my bad an English
This is my code.
while(true)
{
System.out.println("Under While loop...");
if(incoming != null)
{
System.out.println("Data is not blank..." + incoming );
}
else
{
System.out.println("Data is blank..." + incoming );
}
sock.receive(incoming);
System.out.println("Hello..");
byte[] data = incoming.getData();
if(data != null)
{
System.out.println("Data is not blank...");
}
else
{
System.out.println("Data is blank...");
}
String s = new String(data, 0, incoming.getLength());
//echo the details of incoming data - client ip : client port - client message
System.out.println(incoming.getAddress().getHostAddress() + " : " + incoming.getPort() + " : " + s);
if(s != "" )
{
String R = incoming.getAddress().getHostAddress() + " : " + incoming.getPort() + " : " + s;
//lblResultTest.setText(R);
String[] words = s.split("&");
txtResult.setText(words[2]);
this.getAppletContext().showDocument( this.getDocumentBase() );
}
//s = "OK : " + s;
//DatagramPacket dp = new DatagramPacket(s.getBytes() , s.getBytes().length , incoming.getAddress() , incoming.getPort());
//sock.send(dp);
}
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
So, I'm trying to create a function (If not pretty) IRC client using no libraries, written in Java. I've gotten almost everything working, the only problem is that I'm currently getting user input using System.in. And if someone else in the channel sends a message while I'm in the middle of typing, it cuts off what I currently have, and I need to guess where I am in the string. I want to know if there's a way to separate user input from the output of the program, so that this doesn't happen. This is the code in question:
new Thread(() -> {
while(connected[0]) {
String output = sc.nextLine();
if(!output.startsWith("~") && !output.startsWith("/")) {
try {
writeToSocket("PRIVMSG " + focused[0] + " " + output);
} catch (IOException e) {
e.printStackTrace();
}
}
if(output.substring(1).toLowerCase().startsWith("quit")) {
String[] split = output.substring(5).split(" ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
if(i == 0) {
sb.append(split[i]);
}
sb.append(" ").append(split[i]);
}
try {
writeToSocket("QUIT " + sb.toString());
connected[0] = false;
} catch (IOException e) {
e.printStackTrace();
}
}else if(output.substring(1).toLowerCase().startsWith("focus")) {
String get = output.substring(7);
if(!channels.contains(get)) {
print("Not connected to channel");
}else {
try {
writeToSocket("PART " + focused[0]);
writeToSocket("JOIN " + get);
} catch (IOException e) {
e.printStackTrace();
}
focused[0] = get;
}
}else if(output.substring(1).toLowerCase().startsWith("join")) {
String get = output.substring(6);
channels.add(get);
}
if(output.startsWith("/") && output.substring(1).toLowerCase().startsWith("msg")) {
String[] split = output.substring(5).split(" ");
String username = split[0];
StringBuilder msg = new StringBuilder();
for(int i = 1; i < split.length; i++) {
if(i == 1) {
msg.append(split[i]);
continue;
}
msg.append(" ").append(split[i]);
}
try {
writeToSocket("PRIVMSG " + username + " " + msg.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
I have looked a lots of examples and have asked a few people but no one seems to be able to tell me what I am doing wrong on my listen sockets. Please help.
I am making a program that reads from 3 files and then sends data in sockets in threads.
here is every thing I have done
public class Main {
public static void main(String[] args) throws Exception{
//making all threads for A,B and C
Thread T_A = new Thread(new threads ("A"));
Thread T_B = new Thread(new threads ("B"));
Thread T_C = new Thread(new threads ("C"));
//starting the threads for A,B and C
T_A.start();
T_B.start();
T_C.start();
}
}
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class threads implements Runnable {
//making temps
String name;
int listen;
int send;
String line;
BufferedReader reader;
BufferedReader input;
boolean Listening=false;
boolean Sending=false;
PrintWriter output;
ServerSocket node_listen=null;
Socket node_send=null;
Socket node_rev=null;
public threads(String x){
//name of thead A,B or C
name=x;
}
#Override
public void run(){
try{
//openinng the conf file for thread
reader = new BufferedReader(new FileReader("conf" + name + ".txt"));
//this is for node A because it only sends info does not get info
if(name.equals("A")==true){
//making a socket to send on
System.out.println("Node " + name + " is starting");
send = Integer.parseInt(reader.readLine());
for(int temp=0;temp!=5;temp++)
{
temp=Checker(temp);
}
}
//this is for node B becuase it sends and gets info
else if(name.equals("B")==true){
//getting ports for send and listen
listen = Integer.parseInt(reader.readLine());
send = Integer.parseInt(reader.readLine());
System.out.println("Node " + name + " is starting");
Listening=setUpListen();
for(int temp=0;temp!=5;temp++)
{
temp=Checker(temp);
}
}
//node C only gets info
else if(name.equals("C")==true){
//geting listen port
listen = Integer.parseInt(reader.readLine());
System.out.println("Node " + name + " is starting");
Listening=setUpListen();
}
//sends and gets data until it has no more to send or get
while(Listening==true || Sending== true)
{
//while it needs to get data and was a node that gets data
if(Listening==true)
{
Listen();
}
//Has not sent terminate yet and is a sending node
if(Sending==true)
{
Send();
}
}
}
catch(IOException | NumberFormatException e)
{
System.out.println(e);
}
catch (InterruptedException ex)
{
Logger.getLogger(threads.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Node " + name + " has ended");
}
public boolean setUpConnection(){
try {
//making a socket for sending
System.out.println("Node " + name + " is setting up connection");
node_send = new Socket("hostname", send);
output = new PrintWriter(node_send.getOutputStream(),true);
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: " + name + " :" + send);
return false;
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + name + " " + e);
return false;
}
//telling the thread it is a sending thread
Sending=true;
System.out.println("Node " + name + " is ready for sending");
return true;
}
public boolean setUpListen(){
try{
//making socket for Listening
System.out.println("Node " + name + " is setting up listen");
nodeListen = new ServerSocket(listen);
System.out.println("Node " + name + " is trying to listen");
node_rev = node_listen.accept();
System.out.println("Node " + name + " NEVER GETS HERE");
input = new BufferedReader(new InputStreamReader(node_rev.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: " + name + " :" + listen);
return false;
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + name + " " + e);
return false;
}
//telling the thread it is a Listening thread
System.out.println("Node " + name + " is ready for listening");
return true;
}
public void Listen(){
try{
line = input.readLine();
//As long as something was sent and it was not terminate prints data
if(line.equals("terminate")==false&&line.equals("null")==false)
{
System.out.println("Node " + name + " received:" + line);
}
//When terminate was sent it no longer looks for data
if(line.equals("terminate"))
{
Listening=false;
node_listen.close();
node_rev.close();
input.close();
System.out.println("Node " + name + " done listening");
}
}catch (IOException e) {
System.out.println("Error Listening on connection: " + name + " " + e);
}
}
public void Send(){
try{
//reads in the data and sends it to node
line=reader.readLine();
System.out.println(line);
output.println(line);
//if the data sent was terminate then exit sending mode
if(line.equals("terminate")==true)
{
Sending=false;
node_send.close();
output.close();
System.out.println("Node " + name + " done sending");
}
}catch (IOException e) {
System.out.println("Error Sending on connection: " + name + " " + e);
}
}
public int Checker(int temp) throws InterruptedException{
boolean connected=setUpConnection();
if(connected==true)
{
//connected
temp=5;
}
return temp;
}
}
each conf file is setup like this
confA.txt
5002
This is a sample line of text for node A.
This is another sample line of text for node A.
Node B will be printing out these three lines for node A.
terminate
confB.txt
5002
5005
This is a sample line of text.
This is another sample line of text.
Node C will be printing out these three lines.
terminate
confC.txt
5005
That is the out put I get
run:
Node A is starting
Node A is setting up connection
Node B is starting
Node B is setting up listen
Node C is starting
Node C is setting up listen
Node B is trying to listen
Node C is trying to listen
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A has ended
The code never seems to get to the line System.out.println("Node " + name + " NEVER GETS HERE"); in the setUpListen();
Thanks
That is because ServerSocket.accept() blocks until an incoming connection is reported. The method returns the Socket.
So the next line (System.out.println("Node " + name + " NEVER GETS HERE")) is never executed until you get another network interface to connect to your listening ServerSocket.
I don't know exactly what it is you're trying to achieve, but you need to listen for incoming connections in an apart thread:
final ServerSocket serverSocket = createServerSocket();
new Thread(new Runnable() {
#Override
public void run() {
Socket socket = serverSocket.accept();
System.out.println("Incoming connection from " + socket.getInetAddress());
doSomethingWithSocket(socket);
}
}).start();
PS: Please persist with the Java Naming Conventions:
Classes should always start with an Uppercase letter;
Field names (or class attributes) should always start with a lowercase letter;
Method names should always start with a lowercase letter.
It turns out that my problem was node_send = new Socket("hostname", send); should have been node_send = new Socket("localhost", send);
I am dumb.
However I want to thank everyone for there help and pointers.
public class threads ?? Conventions please.
O.t:
Error setting up socket connection: C java.net.BindException: Address already in use
The port that setted up each listener on, is the same. (i.e Address already in use.)
In the code below, I establish the first connection without issue however, when I come back around in my while statement (highlighted in BOLD text below) at the newSocket = serverSocket.accept(); line my program stops there. The objective is to allow multiple connections to one PORT. I'm in the middle of re-factoring an inherited application that has been working but only allowing one connection to one port at a time. This is my first crack at socket programming and any suggestions/direction would be greatly appreciated. Thanks.
Here is the code that I'm working with:
public void connect() {
LOGGER.info("Connecting ... ");
while (!shouldTerminate) {
ActiveSocket activeSocket = null;
Socket newSocket = null;
int tries = 0;
int loopCounter = 0;
if (isServer) {
if (host == null) {
LOGGER.info("Must specify a host ip or host name with HOST configuration tag ");
return;
} else {
// keep accepting new socket connections until you have max active sockets
while (!shouldTerminate && (activeSockets.size() < this.maxActiveSockets)) {
activeSocket = new ActiveSocket();
newSocket = null;
if (serverSocket != null) {
try {
LOGGER.info("Accept socket ");
String ipAddrValue = serverSocket.getInetAddress().toString();
String hostValue = host;
int portValue = serverSocket.getLocalPort();
**newSocket = serverSocket.accept();**
} catch (final IOException ex) {
if (shouldTerminate) {
if (ex.getMessage() != null) {
LOGGER.info(ex.getMessage());
}
} else {
LOGGER.info("IOException while accepting connection ");
LOGGER.warn(FormatData.fullStackTrace(ex));
}
newSocket = null;
}
if (newSocket != null) {
try {
LOGGER.info("Socket keepalive ... ");
newSocket.setKeepAlive(true);
activeSocket.setSocket(newSocket);
increaseConnects();
} catch (final SocketException ex) {
LOGGER.info("SocketException while opening socket ");
LOGGER.warn(FormatData.fullStackTrace(ex));
newSocket = null;
}
}
} else { // first time through the loop
try {
LOGGER.info("Opening server socket (" + host + "," + port + ") for BankID:" + Integer.toString(this.getBankID()));
serverSocket = new ServerSocket(port);
} catch (final IOException ex) {
LOGGER.info("Unable to open server socket socket (" + host + "," + port + ")");
if (ex.getMessage().indexOf("Cannot assign requested address") > -1) {
this.terminate();
final String logMessage = "Invalid IP Address assigned:" + host + ",port:" + port;
final String subject = logMessage;
ATMServer.sendNotification(subject, logMessage);
} else if (tries == 0) {
tries++;
final String logMessage = "Unable to open server socket (" + host + "," + port + ")";
final String subject = "Unable to open server socket (" + host + "," + port + ")";
ATMServer.sendNotification(subject, logMessage);
}
LOGGER.warn(FormatData.fullStackTrace(ex));
}
}
}
}
} else { // client socket -- connecting to a bank
LOGGER.info("Not server and terminal type is null ");
while (!shouldTerminate && (activeSockets.size() < this.maxActiveSockets)) {
activeSocket = new ActiveSocket();
newSocket = null;
if (this.isInForcedStandIn()) {
LOGGER.info("Forced standin " + getName());
try {
Thread.sleep(3000); // #TODO switch to a
// notification when not in
// standin
} catch (final InterruptedException ex) {
LOGGER.info("Interrupted while waiting for connection ");
LOGGER.warn(FormatData.fullStackTrace(ex));
}
} else {
if (!shouldTerminate) {
if ((loopCounter % 120) == 0) {
try {
LOGGER.info("Connecting to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
newSocket = new Socket(InetAddress.getByName(remoteHost), remotePort);
if (newSocket.isConnected()) {
tries = 0;
LOGGER.info("socket connected to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
newSocket.setKeepAlive(true);
if (newSocket.getKeepAlive()) {
LOGGER.info("socket keep alive to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
activeSocket.setSocket(newSocket);
increaseConnects();
} catch (final IOException ex) {
loopCounter++;
tries++;
LOGGER.info("SocketException while opening remote socket (" + remoteHost + "," + remotePort + ") " + " " + ex.getClass() + " " + ex.getMessage());
if ((tries % 300) == 0) {
recordErrorToDatabase(ex.getMessage());
}
}
} else {
loopCounter++;
try {
synchronized (clientConnectLock) {
clientConnectLock.wait(1000);
}
} catch (final InterruptedException inex) {
LOGGER.info("SocketException while opening remote socket " + Thread.currentThread().getName());
LOGGER.warn(FormatData.fullStackTrace(inex));
if (!this.shouldTerminate) {
recordErrorToDatabase("InterruptedException without terminate set.");
}
}
}
}
}
}
}
try {
// here, if we created a new ActiveSocket, establish dataInput and dataOuput streams
// then add to the list of active streams.
// for Discover, this will mean adding up to MaxActiveSockets # of sockets
// to the activeSockets list.
// for each other SwitchChannel, this will be the only activeSocket
if (activeSocket != null) {
LOGGER.info("Creating serverIn/serverOut data streams " + Thread.currentThread().getName());
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(newSocket.getInputStream()));
if (newSocket.isConnected()) {
LOGGER.info("socket still connected to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(newSocket.getOutputStream(), 2048));
activeSocket.setDataInputStream(dataInputStream);
activeSocket.setDataOutputStream(dataOutputStream);
activeSockets.add(activeSocket);
activeSocket.setNumReceivers(this.numReceivers);
ReceiveQueuer[] receiveQueuers = activeSocket.getReceiveQueuers();
LOGGER.info("Starting receive queuers");
for (int cnt = 0; cnt < numReceivers; cnt++) {
receiveQueuers[cnt].setName(this.systemName + "-Socket-" + Integer.toString(activeSockets.size()) + "-ReceiveQueuer-" + Integer.toString(cnt));
receiveQueuers[cnt].setActiveSocket(activeSocket);
receiveQueuers[cnt].start();
}
}
} catch (final Exception ex) {
LOGGER.info("Exception while creating input/output streams " + Thread.currentThread().getName());
LOGGER.warn(FormatData.fullStackTrace(ex));
}
}
if (!shouldTerminate) {
LOGGER.info("Socket connection complete " + Thread.currentThread().getName());
} else {
LOGGER.info("Stopped establishing socket connection " + Thread.currentThread().getName());
}