Simple TCP client/server program in Java - java

Hi I'm having a small problem with my program which is a simple client/server. The client sends the contents of a textfile to the server. The text file is just ints and then the server is suppose to send back the largest prime number less than each int in the text file(if its prime it should just send back the prime number and do nothing). So for instance lets say the text file is 5 15 28. The result after running the program should be 5 13 23.
Here's my code for the Client side:
public class TCPClient {
public static void main(String[] args) throws Exception{
try{
Socket mySock = new Socket("127.0.0.1", 12001);
BufferedReader in = new BufferedReader(
new InputStreamReader(mySock.getInputStream()));
PrintStream out = new PrintStream( mySock.getOutputStream());
Scanner scan = new Scanner(new File(args[0]));
String msg = scan.nextLine();
out.println(msg);
System.out.println(in.readLine());
mySock.close();
}catch (Exception e){
}
}
}
Here's my code for the server side:
public class TCPServer {
public static void main(String[] args) throws Exception {
try{
ServerSocket mySock = new ServerSocket(12001);
Socket client = mySock.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintStream out = new PrintStream( client.getOutputStream());
String[] arr = in.readLine().split(" ");
int[] intarr = new int[arr.length];
for(int i = 0; i <arr.length; i++){
intarr[i] = Integer.parseInt(arr[i]);
if (prim(intarr[i]) == true){
out.println(intarr[i]);
}else{
while (!prim(--intarr[i])){
}
out.println(intarr[i]);
}
}
client.close();
mySock.close();
}catch (Exception e){
}
}
public static boolean prim(int m){
int n=m;
for(int i=2;i<n;i++){
if(n%i == 0){
return false;
}
}
return true;
}
}
When I run this program my output is only the first number in the text file. So if my text file is 1 3 5. My output is just 1. However, my prime algorithm is at least working because if my text file is 8 for instance, my program will return 7. Does anyone know why this is happening?

By change your server code to a simple test and printing to System.out
String[] arr = "1 3 5 6".split(" ");
int[] intarr = new int[arr.length];
for(int i = 0; i <arr.length; i++){
intarr[i] = Integer.parseInt(arr[i]);
if (prim(intarr[i]) == true){
System.out.println(intarr[i]);
}else{
while (!prim(--intarr[i])){
}
System.out.println(intarr[i]);
}
}
you can see that it works OK, but in your code, your output in writing using println, so your client needs to loop System.out.println(in.readLine()); or change your server to write using one line and some delimiter

In TCPServer, when printing to outputstream use print instead of println
for(int i = 0; i <arr.length; i++){
intarr[i] = Integer.parseInt(arr[i]);
if (prim(intarr[i]) == true){
out.print(intarr[i]); // use print instead of println
}else{
while (!prim(--intarr[i])){
}
out.print(intarr[i]); // use print instead of println
}
}

Related

Running Junit Test on Class that gets input from file , but Scanner and BufferedReader objects lead to stack overflow error in the tests

I am running JUnit tests on a method checkFile(), the method is supposed to check a file for some values and prompt the user when the values in the file are not permissible for a new file. If the file is ok, the method returns a value.
The problem is my test fails due to a StackOverflow error each time and never actually runs. The error points to the scanner object I am using to access the file.
I think the issue may be related to my use of recursion in the method but I cannot think of any other way to do this without writing redundant code if I don't use recursion.
Fyi, I know I could break this method into smaller methods but this assignment requires that I do not create any additional methods. I have tried to use BufferedReader Reader = new BufferedReader ( new FileReader(file))
also but the same issue occurs.
Fyi , line 137 in the Simulator class is where I instantiate the object Scanner Reader = new Scanner(file);
public ArrayList<Customer> checkFile(int stops, File file) {
Simulator sim = new Simulator();
int linesProcessed = 0;
String customerdata = " ";
String[] dataArray;
int[] parsedVals = new int[4];
String delimiter = " ";
List<Customer> custList = new ArrayList<Customer>();
List idArray = new ArrayList();
try {
Scanner Reader =new Scanner(file);//--> this appears to be causing the issue.
while (Reader.hasNextLine()) {
customerdata = Reader.nextLine();
dataArray = customerdata.split(delimiter);
for (int i = 0; i < dataArray.length; i++) {
try {
parsedVals[i] = Integer.parseInt(dataArray[i]);
if (parsedVals[i] <=0 ){
System.out.println("file input 0");
throw new IllegalArgumentException();
}
if (i==2 | i==3 ){
if(parsedVals[i]>stops){
throw new IllegalArgumentException();
}
}
} catch (NumberFormatException ex) {
if (linesProcessed == 0) {
System.out.println("Each line must have four integers. Try again.");
} else {
System.out.println(" Regular:Data in input file is not correct. Try again.");
}
sim.getInputFile();
sim.checkFile(stops, file);
}
catch(IllegalArgumentException args){
System.out.println("Data in input file is not correct. Try again.");
file =sim.getInputFile();
custList = sim.checkFile(stops, file);
}
}
try{
if(parsedVals[2]==parsedVals[3]) {
throw new IllegalArgumentException();
}
custList.add(new Customer(parsedVals[0], parsedVals[1], parsedVals[2], parsedVals[3]));
}catch(IllegalArgumentException ex){
System.out.println("Data in input file is not correct. Try again.");
file =sim.getInputFile();
custList = sim.checkFile(stops, file);
}
idArray.add(linesProcessed, parsedVals[0]);
linesProcessed++;
}
boolean duplicates = false;
for (int j = 0; j < idArray.size(); j++) {
for (int k = j + 1; k < idArray.size(); k++) {
if (k != j && idArray.get(k) == idArray.get(j)) {
duplicates = true;
}
}
}
if (duplicates) {
System.out.println(" Duplicates: Data in input file is not correct. Try again.");
File newfile = sim.getInputFile();
sim.checkFile(stops, newfile);
}
}
catch (FileNotFoundException ex) {
System.out.println("File not found, try again.");
file = sim.getInputFile();
sim.checkFile(stops, file);
}
return custList;
}
There are many tests but all the tests essentially do something similar. See bellow :

Send server max integer

Connects to a local server at port 3333, receives a line of integers from the Server, then finds the maximum number of integers and sends that value to the server. I'm placing all values from the line of integers into an arraylist, going through and finding the max; however, when I'm printing to the server, I get a BindException and my test fails.
public static void main(String[] args) {
try {
ArrayList<Integer> val = new ArrayList<Integer>();
// contact the server
Socket socket = new Socket("localhost", 3333);
Scanner scanner = new Scanner(socket.getInputStream());
PrintWriter writer = new PrintWriter(socket.getOutputStream(),
true);
while (scanner.hasNextInt()) {
int num = scanner.nextInt();
val.add(num);
}
int max = val.get(0);
for (int i = 1; i < val.size(); i++) {
if (val.get(i) > max) {
max = val.get(i);
}
}
writer.println(max);
scanner.close();
writer.close();
socket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}

Adding a substring to omit a part of the output

Below is my code...
The code below is taking a .txt file of some radiation read outs. My job is to find the max number of counts per minute in the file within 5 counts.
I'e got it working, but I need to omit the part of the line, so I thought I could make this piece of the code:
/* String temp = new String(data)
* temp=list.get(i);
* System.outprintln(temp.substring(0,16) +" ");
*/
and integrate it in. I keep trying several cases, and am not thinking. Any advice?
`import java.util.*;
//Import utility pack, *look at all classes in package.
import java.io.*;
//Good within directory.
public class counterRadiation {
private static String infile = "4_22_18.txt";
//Input
private static String outfile = "4_22_18_stripped.txt";
private static Scanner reader;
//Output
public static void main(String[] args) throws Exception{
//throw exception and then using a try block
try {
//Use scanner to obtain our string and input.
Scanner play = new Scanner(new File(infile));
/* String temp = new String(data)
* temp=list.get(i);
* System.outprintln(temp.substring(0,16) +" ");
*/
Writer writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outfile), "utf-8"));
String lineSeparator = System.getProperty("line.separator");
play.useDelimiter(lineSeparator);
while (play.hasNext()) {
String line = play.next();
if (line.matches(dataList)) {
writer.write(line + "\r\n");
}
}
writer.close();
play.close();
try {
reader = new Scanner(new File(infile));
ArrayList<String> list = new ArrayList<String>();
while (reader.hasNextLine()) {
list.add(reader.nextLine());
}
int[] radiCount = new int[list.size()];
for (int i = 0; i < list.size();i++) {
String[] temp = list.get(i).split(",");
radiCount[i] = (Integer.parseInt(temp[2]));
}
int maxCount = 0;
for (int i = 0; i < radiCount.length; i++) {
if (radiCount[i] > maxCount) {
maxCount = radiCount[i];
}
}
for (int i = 0;i < list.size() ;i++) {
if(radiCount[i] >= maxCount - 4) {
System.out.println(list.get(i)+" "+ radiCount[i]);
}
}
}catch(FileNotFoundException e){
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}`
Although it is not quite clear what you want to get rid of you could use .indexOf(String str) to define the first occurrence of the sub-string you want to exclude. For example in your code:
String data = "useful bit get rid of this";
int index = data.indexOf("get rid of this");
System.out.println(data.substring(0,index) + "are cool");
//Expected result:
//"useful bits are cool"
from Java doc

Receiving an array of integers from a server in C to a client in Java

How do I receive an array of integers from a server program written in C, to a client program written in Java?
So I send a number to a server and the server should return me an array of the divisors for that number. Here's my piece of code from the server, in C:
void deservire_client(int c) {
// serving the client
int nr, i=2, nrDiv=0, sirDiv[10]={0,0,0,0,0,0,0,0,0,0};
recv(c, &nr, sizeof(nr), MSG_WAITALL);
nr = ntohs(nr);
while ( i <= nr/2){
if ( nr%i == 0){
sirDiv[nrDiv]=i;
nrDiv+=1;
}
i+=1;
}
send(c, &sirDiv, sizeof(sirDiv), 0);
close(c);
So I tested it out and the array of divisors is being created in the server file. As in, it takes the number I send it, and executes the program correctly, ending up with an array of the number's divisors. I then send the reference to my array back to my client program, in Java. However, I'm pretty sure I'm doing something wrong, since once I input a number in the client, nothing happens.
Here's what I'm doing in my Java client program:
public static void main(String args[]) {
Socket socket = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
int nr = readUnsignedShort("nr = ", reader);
byte[] arr = {0,0,0,0,0,0,0,0,0,0};
writeIntegersToSocket(nr, socket);
readArrayFromSocket(socket);
}
private static void readArrayFromSocket(Socket c) throws IOException {
DataInputStream socketIn = new DataInputStream(c.getInputStream());
int i;
InputStream in = c.getInputStream();
DataInputStream dis = new DataInputStream(in);
byte[] data = new byte[10];
dis.readFully(data);
for(i=0; i < data.length; i++)
System.out.println(" " + data[i]);
}

Cyclically call function based on segments of input

I'm working on a class assignment. I need to read in a file containing lines of input. Every block of three lines is a structured set: The first is one polynomial, the second is another polynomial, the third is a text string that indicates the algebraic operation for the polynomial arithmetic. I've set my program up so that it reads each line into an array, and then I parse the two array indices containing integers into my polynomial term. I call the appropriate function based on the third line. My struggle is finding a way to get the process to reset after each third line. Here is the code for my main function. I thought I would use an i-loop (k-loop here) somehow, but I can't get it to work. Any insight or suggestions greatly appreciated.
Example of input:
3 2 4 5
5 7 4 6
subtract
4 3 5 1
1 2 3 4
add
Here is my code:
public static void main(String[] args) throws IOException {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
int lines = 0;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader("Test.txt"));
String line=null;
while((line = reader.readLine()) != null) {
list.add(line);
lines++;
} // end while
} catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("lines " + lines);
for (int k=0; k<lines; k++){
String[] stringArr = list.toArray(new String[0]);
System.out.println(stringArr[k+0]);
System.out.println(stringArr[k+1]);
System.out.println(stringArr[k+2]);
String[] nums1 = stringArr[k+0].split(" ");
String[] nums2 = stringArr[k+1].split(" ");
for (int i=0; i<nums1.length; i+= 2) {
p1.addTerm(Integer.parseInt(nums1[i]), Integer.parseInt(nums1[i+1]));
}
for (int i=0; i<nums2.length; i+= 2) {
p2.addTerm(Integer.parseInt(nums2[i]), Integer.parseInt(nums2[i+1]));
}
if (stringArr[k+2].equalsIgnoreCase("add")) {add(p1,p2);}
else if (stringArr[k+2].equalsIgnoreCase("subtract")) {subtract(p1,p2);}
else if(stringArr[k+2].equalsIgnoreCase("multiply")) {multiply(p1,p2);}
else {
System.out.println("Bad input");
}
nums1=null;
nums2=null;
}
}
Suggestion: Try something like the Scanner class? Catch the NoSuchElementException if it should run out of lines in the file.
Scanner scanner = new Scanner(new String("input"));
while(scanner.hasNextLine()) {
String lineOne = scanner.nextLine();
String lineTwo = scanner.nextLine();
String lineThree = scanner.nextLine();
calculateSomething(lineOne, lineTwo, lineThree);
}
It can be used to read strings to (space-delimited by default)
private static int[] getPolynomialFactors(String line) {
Scanner splitter = new Scanner(line);
int[] p = new int[4];
int counter=0;
while (splitter.hasNextInt()){
p[counter] = splitter.nextInt();
counter++;
}
return p;
}
With a good night's sleep, I was able to figure it out. I used a for-loop and just had to modify the incrementing of the loop counter. I nulled the pointers to the integer arrays I was using to store the integers parsed from the first two lines of the code block, which effectively reset them. Here is my updated code that works:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
int lines = 0;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader("Test.txt"));
String line=null;
while((line = reader.readLine()) != null) {
list.add(line);
lines++;
} // end while
} catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("lines " + lines);
String[] stringArr = list.toArray(new String[0]);
for (int k=0; k<lines; k+=3){
System.out.println(stringArr[k+0]);
System.out.println(stringArr[k+1]);
System.out.println(stringArr[k+2]);
String[] nums1 = stringArr[k+0].split(" ");
String[] nums2 = stringArr[k+1].split(" ");
for (int i=0; i<nums1.length; i+= 2) {
p1.addTerm(Integer.parseInt(nums1[i]), Integer.parseInt(nums1[i+1]));
}
for (int i=0; i<nums2.length; i+= 2) {
p2.addTerm(Integer.parseInt(nums2[i]), Integer.parseInt(nums2[i+1]));
}
if (stringArr[k+2].equalsIgnoreCase("add")) {add(p1,p2);}
else if (stringArr[k+2].equalsIgnoreCase("subtract")) {subtract(p1,p2);}
else if(stringArr[k+2].equalsIgnoreCase("multiply")) {multiply(p1,p2);}
else {
System.out.println("Bad input");
break;
}
nums1=null;
nums2=null;
}
}
}

Categories