String Compare doesnt work after sending data over Tcp - java

I have following code. One reads a File called "denglish.txt" splits it into words and sends every 2nd word over Tcp socket connection to a server. The Server is now supposed to read this word and compare a to a word from a dictionary.
Weird thing is the comparison always fails if i send it that way. But if the clients sends something like out.Print("make") it works .
I really dont understand why its like this. I can send and print out the word from the client on the Server and he prints out the correct words but the stringcompare fails.
MAybe someone can help me. THank you guys
Socket socket = new Socket ("localhost" , 47777);
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
//Socket socket1 = new Socket ("localhost" , 47778);
//PrintWriter out1 = new PrintWriter(socket1.getOutputStream(),true);
String line;
BufferedReader text = new BufferedReader(new InputStreamReader(new FileInputStream("denglisch.txt")));
String text1 = "";
while((line = text.readLine()) != null) { // handle lines
text1 = text1 + line;
}
int i = 0;
//out.println("make");
StringTokenizer tokenizer = new StringTokenizer( text1,",.\" : !" );
while ( tokenizer.hasMoreTokens() )
{
if (i % 2 == 0)
{
out.println(tokenizer.nextToken().toLowerCase().toString());
out.flush();
}
if (i % 2 ==1 )
{
//out1.println(tokenizer.nextToken());
}
i = i+1;
Server CODE
//Server Codepublic
<pre> filteritserver(BufferedReader dict, String plusminus){
this.dict = dict;
this.port = 47777;
this.plusminus = plusminus;
}
public void run() {
ServerSocket server;
boolean isopen = false;
while (isopen == false){
try {
System.out.println(port);
server = new ServerSocket(port);
Socket cSocket = server.accept();
msg = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
isopen = true;
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.println("Port is already in used trying next one");
port = port +1;
}
}
System.err.println(port);
int i = 0;
String s = "word";
try {
while ((word = msg.readLine())!= null)
// while ( i < 3)
{
//System.out.println("prozess started und das Vorzeichen ist "+plusminus);
// System.out.println("das Wort "+ word +" ist hier angekommen");
try {
while(true) { // blunt sequential dictionary search
String line = dict.readLine();
//System.out.println(line);
if(line == null){
break;
}
else if(word.compareTo(line) < 0)
{
if (plusminus.equals("-"))
{
System.out.println("Dieses Wort kommt im Dictionary nicht vor " + word);
}
}
else if(word.compareTo(line)== 0 ){
if (plusminus.equals("+")){
System.out.println("Dieses Wort kommt im Dictionary 1234 vor " + word);
}
break;
}
else /* word.compareTo(line) > 0 */ continue; }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

text1 = text1 + line; You don't use a space or a delimiter in here. Can that be the problem? )(What I mean is that you print several words, like CatHouseDogFood which isn't a word in the dictionary). It would make sense why it works when you only print one word (i.e. "make")
What do you get if you print the compareTo result at server side?

Related

Stuck on readLine() even if the line is null

I wrote this loop in my server, where he just sends some strings to a client:
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
for (int j = 0; j < i; j++) {
out.println(tmp[j]); // send the strings to the client
}
The client has another loop to retrieve all these strings but never exit from there. For example, if I send him 4 strings the output will be:
-hi
-how
-are
-you
And then after this last string it hangs and I cannot do anything else than closing the server. When I close it, the client exit from the while. This is the loop that doesn't work:
/* PHASE 2: The client receives the ArrayList with the emails */
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
String message[] = new String[5];
for (int j=0; ((line = in.readLine()) != null) && (line.length())>0;) {
System.out.println(line); //DEBUG
message[j++] = line;
if (j==5) {
data = format.parse(message[3]);
email.add(new Email((Integer.parseInt(message[0])), message[1], account, message[2], message[4], data));
j=0;
}
}
System.out.println("Out");
Here is the code of the client with the loop incriminated:
public void loadData() throws IOException, ClassNotFoundException, ParseException {
try {
connect();
ArrayList<Email> email = new ArrayList<Email>();
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date data;
/* PHASE 1: The client sends a string to the server */
try {
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
out.println(account+"\n"); // send the account name to server
/* PHASE 2: The client receives the ArrayList with the emails */
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
String message[] = new String[5];
for (int j=0; ((line = in.readLine()) != null) && (line.length())>0;) {
System.out.println(line); //DEBUG
message[j++] = line;
if (j==5) {
data = format.parse(message[3]);
email.add(new Email((Integer.parseInt(message[0])), message[1], account, message[2], message[4], data));
j=0;
}
}
System.out.println("Out");
Here is the server code:
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
private String nomeAccount = "";
public void run() {
try {
incoming = s.accept();
} catch (IOException ex) {
System.out.println("Unable to accept requests");
}
contenutoTextArea.append("Connected from: " + incoming.getLocalAddress() + "\n");
textarea.setText(contenutoTextArea.toString());
try {
//PHASE 1: The server receives the email
try {
BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
nomeAccount = in.readLine();
} catch (IOException ex) {
System.out.println("Not works");
}
//PHASE 2: I'm getting all the emails from the files
File dir = new File("src/server/" + nomeAccount);
String[] tmp = new String[100];
int i = 0;
for (File file : dir.listFiles()) {
if (file.isFile() && !(file.getName().equals(".DS_Store"))) {
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
tmp[i++] = line;
}
br.close();
} catch (IOException ex) {
System.out.println("Cannot read from file");
}
}
}
//PHASE 3: The server sends the ArrayList to the client
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
for (int j = 0; j < i; j++) {
out.println(tmp[j]); // send the strings to the client
}
} catch (IOException ex) {
System.out.println("Cannot send the strings to the client");
}
//PHASE 4: Here I loop and wait for the client choise
BufferedReader in;
String op;
boolean exit = false;
try {
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
while ((op = in.readLine()) != null) {
System.out.println("OP: " + op);
if (op.equals("Elimina")) {
String tmp = in.readLine();
contenutoTextArea.append("Ho eliminato la mail ").append(tmp).append(" \n");
textarea.setText(contenutoTextArea.toString());
File file = new File("src/server/" + nomeAccount + "/" + tmp + ".txt");
file.delete();
}
}
System.out.println("bbbbb");
} catch (IOException ex) {
System.out.println("Unable to read messages");
} finally {
try {
incoming.close();
} catch (IOException ex) {
System.out.println("Cannot close the socket");
}
}
}
}
Based on reading your client code, it looks like it's blocked waiting for another message, and it's not returning null because the end of the stream hasn't been reached. The fact that it continues once you kill the server process validates this.
As noted in the comments, you should make sure you close the PrintWriter on the server side. However, this by itself won't fix it, since the stream is on the socket, and as long as the socket is still open, this won't return null.
You can use specific control strings to communicate state back and forth (things that would never be user input, just to verify that round of communication is finished) then instead of checking for null, you'd check if the line matched the control string. Simply use that technique on both sides to pass control back and forth, and make sure to close the socket when done.

Java Android If Else Break Having Issue Troubleshooting

So this is a function I created.
As you can see this will read for files searching for filename and then it reads for --TEMPERATURE UP--.
Problem is not every filename has a --TEMPERATURE UP-- and
I tried using an else statement but if I remove the break from the else statement, for filename without --TEMPERATURE UP-- the whole app will crash
But if I add a break statement in the else statement, every filename will run the else statement which even if they contains --TEMPERATURE UP--
I have also tried to do a simple else statement without the !line.equals("--TEMPERATURE UP--") but it's still the same.
Either I have to add break at the else to run the else code which will not run the if code OR I remove the break which run the if code but unable to run the else code as it will crash.
Please advise on how I should go about changing my codes such that when it reads --TEMPERATURE UP-- it will run the if code, otherwise it will run the else code.
Thanks alot.
public void tempUp() {
SharedPreferences sharedTest = getSharedPreferences("MySharedTest", Context.MODE_PRIVATE);
String filename = sharedTest.getString("filename", " ");
Log.d("File readed: ", filename);
File dir = new File(path);
File[] files = dir.listFiles();
for (File f : files) {
if (f.isFile()) {
BufferedReader inputStream = null;
try {
inputStream = new BufferedReader(new FileReader(f));
String lineToRead = filename;
String CurrentLine;
while ((CurrentLine = inputStream.readLine()) != null) {
if (CurrentLine.equals(lineToRead)) {
try
{
BufferedReader reader = new BufferedReader(new FileReader(f));
String line = reader.readLine();
while(line !=null)
{
line = reader.readLine();
if(line.equals("--TEMPERATURE UP--"))
{
final String ms = reader.readLine();
Log.d("temp up: ", ms);
new Thread(new Runnable()
{
#Override
public void run()
{
String message = "\u000704NTX" + ms + "\r";
byte[] byte_array = message.getBytes();
try
{
SharedPreferences prefx = getSharedPreferences("Device_Data", Context.MODE_PRIVATE);
String device_ip = prefx.getString("local_ip", " ");
String host = device_ip;
Socket socket = new Socket(host, 8070);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.write(byte_array);
out.flush();
}
catch (Exception e)
{
}
}
}).start();
break;
}
else if (!line.equals("--TEMPERATURE UP--"))
{
Toast.makeText(TestScreen.this, "There is no Temperature Display for this profile.", Toast.LENGTH_LONG).show();
break;
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Updated:
try
{
BufferedReader reader = new BufferedReader(new FileReader(f));
String line = reader.readLine();
boolean hasTempDisplayProfile = false;
while((line = reader.readLine()) !=null)
{
if(line.equals("--TEMPERATURE UP--")) {
hasTempDisplayProfile = true;
final String ms = reader.readLine();
Log.d("temp up: ", ms);
new Thread(new Runnable() {
#Override
public void run() {
String message = "\u000704NTX" + ms + "\r";
byte[] byte_array = message.getBytes();
try {
SharedPreferences prefx = getSharedPreferences("Device_Data", Context.MODE_PRIVATE);
String device_ip = prefx.getString("local_ip", " ");
String host = device_ip;
Socket socket = new Socket(host, 8070);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.write(byte_array);
out.flush();
} catch (Exception e) {
}
}
}).start();
break;
}
}
if (hasTempDisplayProfile){
Toast.makeText(TestScreen.this, "There is no Temperature Display for this profile.", Toast.LENGTH_LONG).show();
break;
}
}
catch (IOException e)
{
e.printStackTrace();
}
Your current implementation is:
while(readLine) {
if (line.equal("--TEMPERATURE UP--") {
// process
} else {
// Toast message
}
}
So do you see the problem now? The problem is your are testing again --TEMPERATURE UP-- for every line and show Toast every time the line is not match.
It's wrong.
What you want is to check if the whole file does not contain the --TEMPERATURE UP--, if so, then show the toast.
So the correct implementation would involving a flag:
boolean hasTempDisplayProfile = false;
while(readLine) {
if (line.equal("--TEMPERATURE UP--") {
// process
hasTempDisplayProfile = true;
}
}
if (!hasTempDisplayProfile) {
// Toast message
}
Edit
Your code has another serious flaw:
String line = reader.readLine();
while(line !=null){
line = reader.readLine();
... your process ...
}
In this code, you read a line. Then check for line not equals null in the while. The problem is you did not use that line but process to read another line = reader.readLine(). It will throw NullPointerException when you reach end of file.
Change to this:
String line;
while((line = reader.readLine()) !=null){
// Do not read new line here. Just process with "line"
}
By the way, your code need improvement. It now has too much indentation, which is very frustrate to read. You can try:
Break your function into smaller modules
Use fail-fast. That is instead of wrap your code if the condition hold true, try to return when false. For example your:
for (File f: files) {
if (f.isFile()) {
// Your process
}
}
should be changed to:
for (File f: files) {
if (!f.isFile()) {
continue;
}
// Your process
}
It reduces one level of indentation.

Manipulating tokens to deal with variable number of strings on one line

I will try to explain this as much as I can. I am reading scores from a file onto which my form appends lines. The line consists of a date, home team, score, away team, score.
The stats I gather is away wins, home wins and draws.
The following code works perfectly
JButton viewStatsButton = new JButton(new AbstractAction("VIEW STATS")
{
public void actionPerformed( ActionEvent e )
{
int homeScore = 0;
int awayScore = 0;
int homeWins = 0;
int awayWins = 0;
int scoreDraw = 0;
String line = null;
String output;
String matchDay;
#SuppressWarnings("unused")
String homeTeam;
#SuppressWarnings("unused")
String awayTeam;
String file = "scores.dat";
StringTokenizer tokenizer;
FileReader fileReader = null;
try
{
fileReader = new FileReader (file);
}
catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
BufferedReader inFile = new BufferedReader (fileReader);
try
{
line = inFile.readLine();
}
catch (IOException e1)
{
e1.printStackTrace();
}
while(line != null)
{
tokenizer = new StringTokenizer(line);
matchDay = tokenizer.nextToken();
homeTeam = tokenizer.nextToken();
try
{
homeScore = Integer.parseInt(tokenizer.nextToken());
}
catch (NumberFormatException exception)
{
System.out.println("Error in input. Line ignored:");
System.out.println(line);
}
awayTeam = tokenizer.nextToken();
try
{
awayScore = Integer.parseInt(tokenizer.nextToken());
}
catch (NumberFormatException exception)
{
System.out.println("Error in input. Line ignored:");
System.out.println(line);
}
if(homeScore > awayScore)
{
homeWins++;
}
else if(awayScore > homeScore)
{
awayWins++;
}
else
{
scoreDraw++;
}
try
{
line = inFile.readLine();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
try
{
inFile.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
output = "Home Wins : "+homeWins+"\nAway Wins : "+awayWins+"\nDraws : "+scoreDraw;
JTextArea textArea = new JTextArea();
frame.getContentPane().add(textArea, BorderLayout.CENTER);
textArea.setText(output);
}
});
scorePanel.add(viewStatsButton);
}
The problem does not come to light until the name of team is made out of two strings i.e.Newcastle United. What I had to do was append the two strings together like NewcastleUnited. I have tried to find out the length of the token and if it's less than 3 then i take it and parse it as integer but it seems that even if the next token reference is in an if statement it still moves to the token after it.
I would appreciate any help and guidance.
Try following
Before calling tokenizer.nextToken() check tokenizer.hasMoreTokens() to ensure that there is a token to read
if(tokenizer.hasMoreTokens())
{
x = tokenizer.nextToken();
}
After reading team name(first part) check whether next part is integer if it is, treat it as score, otherwise append it to team name.
homeTeam = tokenizer.nextToken();
String temp = tokenizer.nextToken();
try
{
homeScore = Integer.parseInt(temp);
}
catch(Exception e)
{
//Comes here if temp is not an integer, so temp is second part of name
homeTeam = homeTeam + " "+temp;
homeScore = Integer.parseInt(tokenizer.nextToken());
}
//Whatever the case, if we come here, it means both hometeam and score are assigned.
...........
...........
...........
Don't forgot to check tokenizer.hasMoreTokens() if you are not sure whether there is a token.

Java connection to Jabber with only Sockets

What type of stream can I use to send a request message over a tcp socket to jabber.
I'm writing a string with xml format.
I cant use any libraries. It has to be pure java sockets.
the following is the code which i used. But the response for the second xml request is null
try {
Socket s = new Socket("195.211.49.6", 5222);
PrintWriter out = new PrintWriter(s.getOutputStream());
out.println("<stream:stream to='nimbuzz.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");
out.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(s
.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
out.println("<iq type='set' xml:lang='en' id='terms' to='nimbuzz.com'><query xmlns='jabber:iq:auth'><username>username</username><password>password</password><resource>resource</resource></query></iq>");
out.flush();
reader = new BufferedReader(new InputStreamReader(s
.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
this is what i have implemented in c#, it works quite fast too.
Socket m_socWorker;
try
{
m_socWorker = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string ipString = "195.211.49.6";
string str2 = "5222";
int port = Convert.ToInt16(str2, 10);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipString), port);
m_socWorker.Connect(remoteEP);
string page=string.Empty, page1=string.Empty, page2=string.Empty;
string s = "<stream:stream to='nimbuzz.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>";
byte[] bytes = Encoding.UTF8.GetBytes(s);
byte[] buffer = new byte[0x4b38];
m_socWorker.Send(bytes, bytes.Length, SocketFlags.None);
int count = 0;
count = m_socWorker.Receive(buffer, buffer.Length, SocketFlags.None);
page = page + Encoding.ASCII.GetString(buffer, 0, count);
byte[] buffer3 = new byte[0x4b38];
int num2 = 0;
num2 = m_socWorker.Receive(buffer3, buffer3.Length, SocketFlags.None);
page1 = page1 + Encoding.ASCII.GetString(buffer3, 0, num2);
if (page1.Replace("\"", "'").IndexOf("<stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>PLAIN TEXT</mechanism></mechanisms><register xmlns='http://jabber.org/features/iq-register'/></stream:features>", 0) != 0)
{
string str3 = "<iq type='set' xml:lang='en' id='Nimbuzz_Login' to='nimbuzz.com'><query xmlns='jabber:iq:auth'><username>username</username><password>password</password><resource>resource</resource></query></iq>";
byte[] buffer4 = new byte[0x30d40];
buffer4 = Encoding.UTF8.GetBytes(str3);
byte[] buffer5 = new byte[0x4b38];
m_socWorker.Send(buffer4, buffer4.Length, SocketFlags.None);
int num3 = 0;
num3 = m_socWorker.Receive(buffer5, buffer5.Length, SocketFlags.None);
page2 = Encoding.ASCII.GetString(buffer5, 0, num3);
string str4 = page2.Replace("\"", "'");
int num4 = 1;
}
}
catch (SocketException)
{
}
catch (Exception)
{
}
You are attaching a 2nd BufferedReader (InputStreamReader (...)) to your stream.
Probably the answer to your second request is being consumed and lost in the first buffer.
Try re-using your initial BufferedReader reader; to read the answer to the second message. Remember that XMPP is a single bi-directional stream, so all interaction happens through the same socket throughout the lifetime of your connection.
-- EDIT --
Q: How should the second request be like?
A: Editing your code to give you a starting point (not checked for compilation, just to give you the idea on how to proceed):
private static final int BUFFER_SIZE = 1024;
// Encapsulate the read process
private String readData(Reader reader) throws IOException {
StringBuilder result = new StringBuilder();
char[] buffer = new char[BUFFER_SIZE]; // [note1]
while (reader.ready()) { // [note2]
int charsRead = reader.read(buffer,0,BUFFER_SIZE-1));
if (charsRead > 0) {
result.append(buffer,0,charsRead);
}
}
return result.toString();
}
public void readStuff() {
try {
Socket s = new Socket("195.211.49.6", 5222);
PrintWriter out = new PrintWriter(s.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
out.println("<stream:stream to='nimbuzz.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");
out.flush();
// Read out the data and print it to the console
System.out.println(readData(bufferedReader));
// Second request over the same socket
out.println("<iq type='set' xml:lang='en' id='terms' to='nimbuzz.com'><query xmlns='jabber:iq:auth'><username>username</username><password>password</password><resource>resource</resource></query></iq>");
out.flush();
// Read out the answer for the second result
System.out.println(readData(bufferedReader));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
Notes:
[1] This buffer can be reused across different requests. There's no actual need to recreate it every time this method is called. I left it there to provide you some anchoring with your C# code.
[2] You are checking for EOF in your code. This will potentially not happen in an XMPP connection. It's better to read the characters that are available in the stream until there're no more. Therefore I'm checking on reader.ready() instead of reader.read(...)>-1
See this question for further discussion on EOF: How do I recognize EOF in Java Sockets?

One thread stopping too early regardless of CyclicBarrier

I am aware of the fact that the following code may seem vulgar, but I am new to these things and just tried everything in order to get it to work..
Problem: Even though I am using (possible in a wrong way) a CyclicBarrier, one - and seems to always be the same - thread stops too soon and prints out his vector, leaving 1 out of 11 of those "Incoming connection" messages absent. There is probably something terribly wrong with the last iteration of my loop, but I can't seem to find what exactly.. Now the program just loops waiting to process the last connection.
public class VectorClockClient implements Runnable {
/*
* Attributes
*/
/*
* The client number is store to provide fast
* array access when, for example, a thread's own
* clock simply needs to be incremented.
*/
private int clientNumber;
private File configFile, inputFile;
int[] vectorClock;
/*
* Constructor
* #param
* - File config
* - int line
* - File input
* - int clients
*/
public VectorClockClient(File config, int line, File input, int clients) {
/*
* Make sure that File handles aren't null and that
* the line number is valid.
*/
if (config != null && line >= 0 && input != null) {
configFile = config;
inputFile = input;
clientNumber = line;
/*
* Set the array size to the number of lines found in the
* config file and initialize with zero values.
*/
vectorClock = new int[clients];
for (int i = 0; i < vectorClock.length; i++) {
vectorClock[i] = 0;
}
}
}
private int parsePort() {
int returnable = 0;
try {
FileInputStream fstream = new FileInputStream(configFile.getName());
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = "";
for (int i = 0; i < clientNumber + 1; i++) {
strLine = br.readLine();
}
String[] tokens = strLine.split(" ");
returnable = Integer.parseInt(tokens[1]);
}
catch (Exception e) {
e.printStackTrace();
}
System.out.println("[" + clientNumber + "] returned with " + returnable + ".");
return returnable;
}
private int parsePort(int client) {
int returnable = 0;
try {
FileInputStream fstream = new FileInputStream(configFile.getName());
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = "";
for (int i = 0; i < client; i++) {
strLine = br.readLine();
}
String[] tokens = strLine.split(" ");
returnable = Integer.parseInt(tokens[1]);
}
catch (Exception e) {
e.printStackTrace();
}
return returnable;
}
private int parseAction(String s) {
int returnable = -1;
try {
FileInputStream fstream = new FileInputStream(configFile.getName());
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String[] tokens = s.split(" ");
if (!(Integer.parseInt(tokens[0]) == this.clientNumber + 1)) {
return -1;
}
else {
if (tokens[1].equals("L")) {
vectorClock[clientNumber] += Integer.parseInt(tokens[2]);
}
else {
returnable = Integer.parseInt(tokens[2]);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return returnable;
}
/*
* Do the actual work.
*/
public void run() {
try {
InitClients.barrier.await();
}
catch (Exception e) {
System.out.println(e);
}
int port = parsePort();
String hostname = "localhost";
String strLine;
ServerSocketChannel ssc;
SocketChannel sc;
FileInputStream fstream;
DataInputStream in;
BufferedReader br;
boolean eof = false;
try {
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(hostname, port));
ssc.configureBlocking(false);
fstream = new FileInputStream("input_vector.txt");
in = new DataInputStream(fstream);
br = new BufferedReader(new InputStreamReader(in));
try {
InitClients.barrier.await();
}
catch (Exception e) {
System.out.println(e);
}
while (true && (eof == false)) {
sc = ssc.accept();
if (sc == null) {
if ((strLine = br.readLine()) != null) {
int result = parseAction(strLine);
if (result >= 0) {
//System.out.println("[" + (clientNumber + 1)
//+ "] Send a message to " + result + ".");
try {
SocketChannel client = SocketChannel.open();
client.configureBlocking(true);
client.connect(
new InetSocketAddress("localhost",
parsePort(result)));
//ByteBuffer buf = ByteBuffer.allocateDirect(32);
//buf.put((byte)0xFF);
//buf.flip();
//vectorClock[clientNumber] += 1;
//int numBytesWritten = client.write(buf);
String obj = Integer.toString(clientNumber+1);
ObjectOutputStream oos = new
ObjectOutputStream(
client.socket().getOutputStream());
oos.writeObject(obj);
oos.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
else {
eof = true;
}
}
else {
ObjectInputStream ois = new
ObjectInputStream(sc.socket().getInputStream());
String clientNumberString = (String)ois.readObject();
System.out.println("At {Client[" + (clientNumber + 1)
+ "]}Incoming connection from: "
+ sc.socket().getRemoteSocketAddress()
+ " from {Client[" + clientNumberString + "]}");
sc.close();
}
try {
InitClients.barrier.await();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
printVector();
}
private void printVector() {
System.out.print("{Client[" + (clientNumber + 1) + "]}{");
for (int i = 0; i < vectorClock.length; i++) {
System.out.print(vectorClock[i] + "\t");
}
System.out.println("}");
}
}
To clarify, here are the formats of the files used. Config contains hostnames and ports used by clients that are threads and input file's rows mean either "this client sends a message to that client" or "this client increments his logical clock by some constant value".
1 M 2 (M means sending a message)
2 M 3
3 M 4
2 L 7 (L means incrementing clock)
2 M 1
...
127.0.0.1 9000
127.0.0.1 9001
127.0.0.1 9002
127.0.0.1 9003
...
I would look at the logic related to when you are expecting an incoming socket connection. From your question it looks like you expect a certain number of incoming socket connections (potentially an incoming connection after every outgoing message?). Since you are using non-blocking I/O on the incoming socket it is always possible that your while statement loops before an incoming socket could be established. As a result, a thread would be able to continue and read the next line from the file without receiving a connection. Since your end state is reached once the end of the file is reached, it is possible that you may miss an incoming socket connection.
I would add some simple print outs that displays when you read from the file, when you send a message and when you receive an incoming connection. That should quickly tell you whether or not a particular thread is missing an expected incoming connection. If it turns out that the problem is due to the non-blocking I/O, then you may need to disable non-blocking I/O when you expect an incoming socket or implement a control that keeps track of how many incoming sockets you expect and continues until that goal is met.
Hope this helps.

Categories