I'm trying to develop a client-server exchange program, and when I try to send data from client to server, I'm running into a SocketException. I've looked at other answers but none of them fit my exact case; I have two calls to osw.write, and only one of them works.
Client:
package me.primesearch.client;
import java.math.BigInteger;
import java.net.*;
import java.io.*;
public class PrimeSearchClient {
public static void main(String[] args) throws IOException{
Socket connection = null;
try{
/** Define a host server */
String host = "localhost";
/** Define a port */
int port = 25564;
StringBuffer instr = new StringBuffer();
System.out.println("SocketClient initialized");
/** Obtain an address object of the server */
InetAddress address = InetAddress.getByName(host);
/** Establish a socket connetion */
connection = new Socket(address, port);
/** Instantiate a BufferedOutputStream object */
BufferedOutputStream bos = new BufferedOutputStream(connection.
getOutputStream());
/** Instantiate a BufferedInputStream object for reading
/** Instantiate a BufferedInputStream object for reading
* incoming socket streams.
*/
BufferedInputStream bis = new BufferedInputStream(connection.
getInputStream());
/**Instantiate an InputStreamReader with the optional
* character encoding.
*/
InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");
/**Read the socket's InputStream and append to a StringBuffer */
int c;
/** Instantiate an OutputStreamWriter object with the optional character
* encoding.
*/
OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");
while(true){
String process = "drq " + (char) 13;
/** Write across the socket connection and flush the buffer */
osw.write(process);
osw.flush();
while ( (c = isr.read()) != 13)
instr.append( (char) c);
for(int i=0;i<50;i++){
BigInteger offset=new BigInteger(instr.toString()).add(BigInteger.valueOf(i));
if(isProbablyPrime(offset)){
process = "pri" + " " + offset + " " + (offset.divide(new BigInteger("50"))).toString() + (char) 13;
System.out.println(process);
/** Write across the socket connection and flush the buffer */
osw.write(process); //This doesn't work
osw.flush();
System.out.println("Prime found at " + offset);
}
}
}
} catch(IOException e) {
e.printStackTrace();
} finally {
connection.close();
}
}
public static boolean isProbablyPrime(BigInteger n) {
if(n.longValue()!=0){
BigInteger lessOne = n.subtract(BigInteger.ONE);
// get the next prime from one less than number and check with the number
return lessOne.nextProbablePrime().compareTo(n) == 0;
}
return false;
}
}
Server:
package me.primesearch.server;
import java.net.*;
import java.io.*;
public class PrimeSearchServer implements Runnable {
private Socket connection;
#SuppressWarnings("unused")
private int ID;
PrimeSearchServer(Socket s, int i) {
this.connection = s;
this.ID = i;
}
#SuppressWarnings("resource")
public static void main(String[] args) {
int port = 25564;
int count = 0;
try{
ServerSocket socket1 = new ServerSocket(port);
System.out.println("MultipleSocketServer Initialized");
while (true) {
Socket connection = socket1.accept();
Runnable runnable = new PrimeSearchServer(connection, ++count);
Thread thread = new Thread(runnable);
thread.start();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
BufferedInputStream is = new BufferedInputStream(connection.getInputStream());
InputStreamReader isr = new InputStreamReader(is);
int character;
StringBuffer process = new StringBuffer();
while((character = isr.read()) != 13) {
process.append((char)character);
}
System.out.println(process);
String returnCode="0";
if(process.toString().split(" ")[0].equals("drq")){
System.out.println("Job request recieved");
File file = new File("packages.txt");
//Process input
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
String prevLine="";
boolean i = false;
int count=0;
while ((line = br.readLine()) != null) {
System.out.println("Looking for a package to send");
// process the line.
if(line.equals("0")){
System.out.println("Sending package " + count);
returnCode = Integer.toString(count);
i = true;
break;
}
prevLine = line;
count++;
System.out.println("No packages found");
}
if(!i){
returnCode = prevLine;
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("packages.txt", true)))) {
System.out.println("Creating new package");
out.println("0");
returnCode=Integer.toString(count);
}catch (IOException e) {
e.printStackTrace();
}
}
}
} else if (process.toString().split(" ")[0].equals("pri")){
System.out.println("Prime request recieved");
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("primes.txt", true)))) {
out.println(Integer.parseInt(process.toString().split(" ")[1]));
}catch (IOException e) {
e.printStackTrace();
}
updateLine(Integer.parseInt(process.toString().split(" ")[2]));
}
BufferedOutputStream os = new BufferedOutputStream(connection.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
osw.write(returnCode + (char)13);
osw.flush();
process = new StringBuffer();
}
catch (Exception e) {
System.out.println(e);
}
finally {
try {
connection.close();
}
catch (IOException e){
e.printStackTrace();
}
}
}
private void updateLine(int lines) throws IOException {
String data="packages.txt";
BufferedReader file = new BufferedReader(new FileReader(data));
String input = "";
String line;
for(int i=0;i<lines;i++){
input+=file.readLine()+System.lineSeparator();
}
file.readLine();
while ((line = file.readLine()) != null)
input += line + System.lineSeparator();
FileOutputStream os = new FileOutputStream(data);
os.write(input.getBytes());
file.close();
os.close();
}
}
Sorry if the indenting on the code looks a bit strange, I'm not used to using stack overflow.
You are closing the socket in your server class:
finally {
try {
connection.close();
}
catch (IOException e){
e.printStackTrace();
}
}
I think this is the problem. This is the first message you're sending to the server.
Client
String process = "drq " + (char) 13;
osw.write(process);
osw.flush();
And since your server stops reading after it gets a 13 char it closes the connection after it reads the first message.
Server
while((character = isr.read()) != 13) {
process.append((char)character);
}
I was getting the same exception when running functional test using TestNG. For me it was a version issue. Uninstalling it and installing older version fixed my issue. Read the following post for information.
https://github.com/cbeust/testng-eclipse/issues/91
Related
I want to send file from client to server using socket.
But at the server, I only receive the first line. What is the problem?
Server Code
public static void main(String ars[]){
int port = 1000;
try {
ServerSocket sercoc = new ServerSocket(port);
System.out.println("dkjd");
while (true){
Socket soc = sercoc.accept();
InputStream flux = soc.getInputStream();
BufferedReader entree = new BufferedReader(new InputStreamReader(flux));
String message = entree.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Client Code
public static void main(String args[]){
String hote = "127.00.0.1";
int port = 1000;
FileReader input = null;
File file = new File("src/view/files/temperature2.txt");
Socket soc = null;
try {
soc = new Socket(hote,port);
OutputStream flux = soc.getOutputStream();
OutputStreamWriter sortie = new OutputStreamWriter(flux);
try {
input = new FileReader("src/view/files/temperature2.txt");
char c;
while ((c = (char) input.read()) != -1){
sortie.write(c);
//sortie.write("\n");
}
} finally {
if (input != null){
input.close();
}
}
sortie.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
If I use BufferedReader I found errors and I can't receive anything!
in my code I have implemented the transfer of photo, txt and zip files through ObjectOutputStream and ObjectInputStream.
code:
// output
ObjectOutputStream objectOutput = new ObjectOutputStream(connection.clientSocket.getOutputStream());
objectOutput.writeObject(your_file);
// input
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
buffer = (byte[]) ois.readObject();
I am trying to implement multi threading with a client/server program I have been working on. I need to allow multiple clients to connect to the server at the same time. I currently have 4 classes: a Client, a Server, a Protocol and a Worker to handle the threads. The following code is what I have for those classes:
SocketServer Class:
public class SocketServer {
public static void main(String[] args) throws IOException {
int portNumber = 9987;
try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
Thread thread = new Thread(new ClientWorker(clientSocket));
thread.start(); //start thread
String inputLine, outputLine;
// Initiate conversation with client
Protocol prot = new Protocol();
outputLine = prot.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = prot.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("quit"))
break;
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
SocketClient Class:
public class SocketClient {
public static void main(String[] args) throws IOException
{
String hostName = "localhost";
int portNumber = 9987;
try (
Socket socket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
) {
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("quit"))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostName);
System.exit(1);
}
}
}
Protocol Class:
public class Protocol {
private static final int waiting = 0;
private static final int sentPrompt = 1;
private int status = waiting;
public String processInput(String theInput) {
String theOutput = null;
if (status == waiting) {
theOutput = "Please enter what you would like to retrieve: 'customer' or 'product' ";
status = sentPrompt;
}
else if ( status == sentPrompt ) {
if ( theInput.equalsIgnoreCase("product")) {
File f = new File("product.txt");
Scanner sc = null;
try {
sc = new Scanner(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(Protocol.class.getName()).log(Level.SEVERE, null, ex);
}
while ( sc.hasNextLine() ) {
String line = sc.nextLine();
theOutput = "The current product entries are : " + line;
}
return theOutput;
}
else if ( theInput.equalsIgnoreCase("customer")) {
File f = new File("customer.txt");
Scanner sc = null;
try {
sc = new Scanner(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(Protocol.class.getName()).log(Level.SEVERE, null, ex);
}
while ( sc.hasNextLine() ) {
String line = sc.nextLine();
theOutput = "The current customer entries are : " + line;
}
return theOutput;
}
else if ( theInput.equalsIgnoreCase("quit")) {
return "quit";
}
else {
return "quit";
}
}
return theOutput;
}
}
The ClientWorker Class:
public class ClientWorker implements Runnable {
private final Socket client;
public ClientWorker( Socket client ) {
this.client = client;
}
#Override
public void run() {
String line;
BufferedReader in = null;
PrintWriter out = null;
try {
System.out.println("Thread started with name:"+Thread.currentThread().getName());
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while (true) {
try {
System.out.println("Thread running with name:"+Thread.currentThread().getName());
line = in.readLine();
//Send data back to client
out.println(line);
//Append data to text area
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
}
}
}
When I run the server and client, everything works fine as expected. Then when I try to run another client, it just hangs there and does not prompt the client to give a response. Any insight into what I am missing is greatly appreciated!
Your server code should address implement below functionalities.
Keep accepting socket from ServerSocket in a while loop
Create new thread after accept() call by passing client socket i.e Socket
Do IO processing in client socket thread e.g ClientWorker in your case.
Have a look at this article
Your code should be
ServerSocket serverSocket = new ServerSocket(portNumber);
while(true){
try{
Socket clientSocket = serverSocket.accept();
Thread thread = new ClientWorker(clientSocket);
thread.start(); //start thread
}catch(Exception err){
err.printStackTrace();
}
}
How many times does serverSocket.accept() get called?
Once.
That's how many clients it will handle.
Subsequent clients trying to contact will not have anybody listening to receive them.
To handle more clients, you need to call serverSocket.accept() in a loop.
Server starts here:
public static void main(String[] args){
System.out.println("Server has started");
try {
ServerSocket socket = new ServerSocket(17000);
while(true){
ThreadedClass w;
w = new ThreadedClass(socket.accept());
Thread t = new Thread(w);
t.start();
}
} catch (IOException e) {
System.out.print("Failed");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Then this class:
package com.sandislandsrv.rourke750;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ThreadedClass implements Runnable{
private Socket socket;
public ThreadedClass(Socket socket){
this.socket = socket;
}
#Override
public void run() {
MysqlDataClass db = Start.getData();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
String cred = in.readLine();
String[] creds = cred.split(" ");
System.out.print(creds[0] + creds[1]);
boolean authenticate = db.getUsernamePassValid(creds[0], creds[1]);
if (!authenticate){
System.out.println("Failed to log in, bad password");
out.println("BAD");
out.close();
return;
}
out.println("GOOD");
String line;
while ((line = in.readLine()) != null){
if (line.equals("END")){
out.close();
return;
}
if (line.equals("GET")){
out.println(db.getMessages(creds[0]));
}
if (line.equals("IN")) break;
if (line.equals("REMOVE")){
line = in.readLine();
db.removeMessage(creds[0], line);
}
}
line = in.readLine();
String[] format = line.split("Theamjgfdngkngfd8998906504906595665");
String[] timeformat = format[1].split(":");
long time = System.currentTimeMillis()/1000;
if (Long.parseLong(timeformat[0]) != 0)
time += 3600 * Long.parseLong(timeformat[0]);
if (Long.parseLong(timeformat[1]) != 0)
time += 60 * Long.parseLong(timeformat[1]);
if (Long.parseLong(timeformat[2]) != 0)
time += Long.parseLong(timeformat[2]);
db.addMessage(creds[0], format[0], time);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void remove(){
}
}
Then later on I call this method
public String[] getNames(){
StringBuilder builder = new StringBuilder();
try {
Socket socket = new Socket("share.betterassociations.com", 17000);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println(username.getText().toString() + " " + password.getText().toString());
System.out.print("test");
String passed = input.readLine();
System.out.print("test2");
if (passed.equals("BAD")) {
System.out.print("fail");
loginerror.setVisible(true);
socket.close();
return null;
}
System.out.print("test2");
out.println("GET");
String line;
while ((line = input.readLine()) != null){
if (line.equals("END")) break;
builder.append(line);
}
out.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return builder.toString().split(" ");
}
For some reason it seems to get frozen in the last method posted with the String passed = input.readLine();
I don't understand why its happening because I am sending a string to the client from the server but the client isn't receiving it.
Add a call to out.flush() after you write to it for both server and clients' outputStreams, like here
....
out.println("GOOD");
out.flush();
....
Alternatively, enable autoflushing by changing your server (the client is already enabled) here:
....
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
....
But per the documentation:
if automatic flushing is enabled it will be done only when one of the println, printf, or format methods is invoked, rather than whenever a newline character happens to be output.
So don't get gotchya'ed
I am making a simple ftp client/server program which on command from the clients lists files, tells the current directory, downloads files
My client code works fine since i have already tested it with a working server. However the server that i have designed gets stuck in the run() function on the line String message = br.readline(); If instead i use the br.read(), then it works but i need command in form of a string to know which file i have to download whereas br.read() returns int. Here's my code, i have used threading.
public class Myserver {
static final int PortNumber = 108;
static ServerSocket MyService;
static Socket clientSocket = null;
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
File directory;
directory = new File(System.getProperty("user.home"));
try {
MyService = new ServerSocket(PortNumber);
String cd = directory.toString();
System.out.println(cd);
System.out.println("Listening on " + PortNumber);
while(true) {
clientSocket = MyService.accept();
Connecthandle a = new Connecthandle(clientSocket, directory);
a.run();
}
}
catch (IOException e) {
System.out.println(e);
}
}
static class Connecthandle extends Thread {
File Directory;
Socket clientsocket;
// Constructor for class
Connecthandle(Socket clients, File dir) {
clientsocket = clients;
Directory = dir;
}
// Works Fine
void listfiles() throws IOException {
String []Listfile = Directory.list();
String send = "";
for (int j = 0; j < Listfile.length; j++) {
send = send + Listfile[j] + ",";
}
DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
GoingOut.writeBytes(send);
GoingOut.flush();
GoingOut.close();
}
// Works Fine
void currentdirectory() throws IOException {
String cd = Directory.toString();
String cdd = "resp," + cd;
System.out.println(cdd);
DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
GoingOut.writeBytes(cdd);
GoingOut.flush();
GoingOut.close();
System.exit(0);
}
void sendfiles(String fileName) {
try {
File nfile = new File(fileName);
DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
if ( (! nfile.exists()) || nfile.isDirectory() ) {
GoingOut.writeBytes("file not present");
} else {
BufferedReader br = new BufferedReader(new FileReader(nfile));
String line;
while ((line = br.readLine()) != null) {
line = br.readLine();
GoingOut.writeBytes(line+"\n");
}
GoingOut.flush();
GoingOut.close();
br.close();
}
} catch (IOException e) {
System.out.println("Unable to send!");
}
}
#SuppressWarnings("deprecation")
public void run() {
try {
DataInputStream comingin = new DataInputStream(clientsocket.getInputStream());
InputStreamReader isr = new InputStreamReader(comingin, "UTF-8");
BufferedReader br = new BufferedReader(isr);
System.out.println("here");
// if (br.ready())
String message = br.readLine(); // Code gets stuck here, if i use br.read() it works, but i need string output.
if (message.equals("listfiles\n")) {
listfiles();
} else if (message.equals("pwd")) {
currentdirectory();
} else if (message.contains("getfile,")) {
String fileName = new String(message.substring(8, message.length()));
sendfiles(fileName);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
clientsocket.close();
} catch (IOException e) {}
}
}
}
}
If readLine() is blocking and you are sending data, you aren't sending a newline.
Ok so I have constructed a working example of a client and server which can accept multiple client connections. My problem is is that I cannot connect a client which is not running the same internet connection as the one the server is being hosted on. Is this possible using server sockets?
Here is the code for my server:
import java.io.IOException;
import java.net.*;
public class MultipleSocketServer {
public static Socket connection;
public static String name = "Tyler's Server";
public static int limit = 2;
public static Thread[] clients = new Thread[limit];
public static int current = 0;
public static int port = 25565;
public static String[] connected = new String[limit];
public static ServerSocket socket;
public static void main(String[] args) {
System.out.println("Server starting...");
for(int i = 0; i < limit; i++) {
connected[i] = "";
}
try {
ServerSocket socket = new ServerSocket(port);
while(true) {
Socket connection = socket.accept();
String ip = connection.getRemoteSocketAddress().toString().substring(1, 13);
loop:
for(int i = 0; i < connected.length; i++) {
if(connected[0].equals(ip) || connected[1].equals(ip)) {
break loop;
}else if(!connected[i].equals(ip)) {
connected[i] = ip;
MultiServer_Client client = new MultiServer_Client(connection, i);
Thread run = new Thread(client);
run.start();
break loop;
}
}
}
} catch (IOException e1) {
System.out.println("Could not bind server on: " + port);
System.exit(-1);
}
}
}
And here is the rest:
import java.io.*;
import java.net.Socket;
public class MultiServer_Client implements Runnable {
public String time;
public Socket client;
public StringBuffer process = new StringBuffer();
public BufferedInputStream inputStream;
public InputStreamReader reader;
public BufferedOutputStream outputStream;
public OutputStreamWriter writer;
public StringVis check = new StringVis("");
public StringChangeListener checkListener = new StringChangeListener() {
public void textChanged(StringChangeEvent e) {
System.out.println("Changed");
write("Server recieved message...");
}
};
public boolean connected = true;
public int ID;
public MultiServer_Client(Socket connection, int i) {
client = connection;
ID = i;
try {
//declare text input/output
inputStream = new BufferedInputStream(client.getInputStream());
reader = new InputStreamReader(inputStream);
outputStream = new BufferedOutputStream(client.getOutputStream());
writer = new OutputStreamWriter(outputStream, "US-ASCII");
} catch (IOException e) {
System.out.println("IOException: " + e);
}
System.out.println(MultipleSocketServer.connected[ID] + " connected...");
write("Connected to " + MultipleSocketServer.name);
}
public void run() {
while(connected) {
read();
}
System.out.println("Disconnecting client...");
}
public void write(String authen) {
try {
time = new java.util.Date().toString();
String message = time + ": " + authen + (char) 13;
writer.write(message);
writer.flush();
} catch (IOException e) {
connected = false;
MultipleSocketServer.connected[ID] = "";
}
}
public void read() {
//read from client
int character;
process = new StringBuffer();
try {
while ((character = reader.read()) != 13) {
process.append((char) character);
}
check.setText(process.toString());
process.delete(0, process.length());
} catch (IOException e) {
connected = false;
MultipleSocketServer.connected[ID] = "";
}
}
}
Here's the client code:
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class SocketClient {
public static String host = "69.182.134.79";
public static int port = 25565;
public static void main(String [] args) {
StringBuffer imports = new StringBuffer();
String time;
System.out.println("Client starting...");
try {
//establish client
InetAddress address = InetAddress.getByName(host);
Socket connection = new Socket(address, port);
BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");
while(true) {
Scanner scan = new Scanner(System.in);
String message = scan.nextLine();
//write to server
time = new java.util.Date().toString();
String process = host + ":" + port + " sent data at " + time + ": " + message + (char) 13;
osw.write(process);
osw.flush();
//read from server
int c;
while ((c = isr.read()) != 13) {
imports.append((char) c);
}
System.out.println(imports);
imports.replace(0, imports.length(), "");
if(message.equals("--EXIT")) {
connection.close();
}
}
} catch (UnknownHostException e) {
System.out.println("UnknownHostException: " + e);
} catch (IOException e) {
System.out.println("IOExcepion: " + e);
}
}
}
Change
MultiServer_Client client = new MultiServer_Client(connection, i);
to
MultiServer_Client client = new MultiServer_Client(new Socket([Server IP], port), i);
This should work.