This is an assignment.
Im looking for a bit of advice as to where i am going wrong here. My aim is to read text from a file, send it to the server and write that text into a new file.
Problem being im not exactly sure how to do it, I have looked at many examples none of which being much help.
To explain the program as is. The user would be asked to input a code which relates to an if statemnt of that code. The one i want to focus on is code 200 which is the upload file to server code.
When i run the code i have i get this error below. Could someone explain to me where i am going wrong, I'd appreciate it.
Connection request made
Enter Code: 100 = Login, 200 = Upload, 400 = Logout:
200
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at MyStreamSocket.receiveMessage(MyStreamSocket.java:50)
at EchoClientHelper2.getEcho(EchoClientHelper2.java:34)
at EchoClient2.main(EchoClient2.java:99)
And this error on the server:
Waiting for a connection.
connection accepted
message received: 200
java.net.SocketException: Socket is not connected
at java.net.Socket.getInputStream(Unknown Source)
at EchoServer2.main(EchoServer2.java:71)
Your MyStreamSocket class does not need to extend Socket. The mysterious error message is because the Socket represented by MyStreamSocket is never connected to anything. The Socket referenced by its socket member is the one that is connected. Hence when you get the input stream from MyStreamSocket it genuinely is not connected. That causes an error, which means the client shuts down. That causes the socket to close, which the server duly reports
The use of BufferedReader is going to cause you problems. It always reads as much as it can into its buffer, so at the start of a file transfer it will read the "200" message and then the first few Kb of the file being sent which will get parsed as character data. The result will be a whole heap of bugs.
I suggest you get rid of BufferedReader right now and use DataInputStream and DataOutputStream instead. You can use the writeUTF and readUTF methods to send your textual commands. To send the file I would suggest a simple chunk encoding.
It's probably easiest if I give you code.
First your client class.
import java.io.*;
import java.net.InetAddress;
public class EchoClient2 {
public static void main(String[] args) {
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
File file = new File("C:\\MyFile.txt");
try {
System.out.println("Welcome to the Echo client.\n"
+ "What is the name of the server host?");
String hostName = br.readLine();
if( hostName.length() == 0 ) // if user did not enter a name
hostName = "localhost"; // use the default host name
System.out.println("What is the port number of the server host?");
String portNum = br.readLine();
if( portNum.length() == 0 ) portNum = "7"; // default port number
MyStreamSocket socket = new MyStreamSocket(
InetAddress.getByName(hostName), Integer.parseInt(portNum));
boolean done = false;
String echo;
while( !done ) {
System.out.println("Enter Code: 100 = Login, 200 = Upload, 400 = Logout: ");
String message = br.readLine();
boolean messageOK = false;
if( message.equals("100") ) {
messageOK = true;
System.out.println("Enter T-Number: (Use Uppercase 'T')");
String login = br.readLine();
if( login.charAt(0) == 'T' ) {
System.out.println("Login Worked fantastically");
} else {
System.out.println("Login Failed");
}
socket.sendMessage("100");
}
if( message.equals("200") ) {
messageOK = true;
socket.sendMessage("200");
socket.sendFile(file);
}
if( (message.trim()).equals("400") ) {
messageOK = true;
System.out.println("Logged Out");
done = true;
socket.sendMessage("400");
socket.close();
break;
}
if( ! messageOK ) {
System.out.println("Invalid input");
continue;
}
// get reply from server
echo = socket.receiveMessage();
System.out.println(echo);
} // end while
} // end try
catch (Exception ex) {
ex.printStackTrace();
} // end catch
} // end main
} // end class
Then your server class:
import java.io.*;
import java.net.*;
public class EchoServer2 {
static final String loginMessage = "Logged In";
static final String logoutMessage = "Logged Out";
public static void main(String[] args) {
int serverPort = 7; // default port
String message;
if( args.length == 1 ) serverPort = Integer.parseInt(args[0]);
try {
// instantiates a stream socket for accepting
// connections
ServerSocket myConnectionSocket = new ServerSocket(serverPort);
/**/System.out.println("Daytime server ready.");
while( true ) { // forever loop
// wait to accept a connection
/**/System.out.println("Waiting for a connection.");
MyStreamSocket myDataSocket = new MyStreamSocket(
myConnectionSocket.accept());
/**/System.out.println("connection accepted");
boolean done = false;
while( !done ) {
message = myDataSocket.receiveMessage();
/**/System.out.println("message received: " + message);
if( (message.trim()).equals("400") ) {
// Session over; close the data socket.
myDataSocket.sendMessage(logoutMessage);
myDataSocket.close();
done = true;
} // end if
if( (message.trim()).equals("100") ) {
// Login
/**/myDataSocket.sendMessage(loginMessage);
} // end if
if( (message.trim()).equals("200") ) {
File outFile = new File("C:\\OutFileServer.txt");
myDataSocket.receiveFile(outFile);
myDataSocket.sendMessage("File received "+outFile.length()+" bytes");
}
} // end while !done
} // end while forever
} // end try
catch (Exception ex) {
ex.printStackTrace();
}
} // end main
} // end class
Then the StreamSocket class:
public class MyStreamSocket {
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
MyStreamSocket(InetAddress acceptorHost, int acceptorPort)
throws SocketException, IOException {
socket = new Socket(acceptorHost, acceptorPort);
setStreams();
}
MyStreamSocket(Socket socket) throws IOException {
this.socket = socket;
setStreams();
}
private void setStreams() throws IOException {
// get an input stream for reading from the data socket
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
}
public void sendMessage(String message) throws IOException {
output.writeUTF(message);
output.flush();
} // end sendMessage
public String receiveMessage() throws IOException {
String message = input.readUTF();
return message;
} // end receiveMessage
public void close() throws IOException {
socket.close();
}
public void sendFile(File file) throws IOException {
FileInputStream fileIn = new FileInputStream(file);
byte[] buf = new byte[Short.MAX_VALUE];
int bytesRead;
while( (bytesRead = fileIn.read(buf)) != -1 ) {
output.writeShort(bytesRead);
output.write(buf,0,bytesRead);
}
output.writeShort(-1);
fileIn.close();
}
public void receiveFile(File file) throws IOException {
FileOutputStream fileOut = new FileOutputStream(file);
byte[] buf = new byte[Short.MAX_VALUE];
int bytesSent;
while( (bytesSent = input.readShort()) != -1 ) {
input.readFully(buf,0,bytesSent);
fileOut.write(buf,0,bytesSent);
}
fileOut.close();
}
} // end class
Ditch the "helper" class. It is not helping you.
Related
I made two classes in Java named Server.java and Client.java. The Server is listening to a port and is waiting for a Client to connect (using sockets). When the client connects he can type a pair of numbers separated by "space" and if that pair exists in my edge_list.txt file the Server returns "1" to the client, if not it returns "0". After I completed my initial project I wanted to also use Threads so that it can handle multiple users at once, but when the Client connects I get -> java.net.SocketException: Socket is closed.
I reviewed my code and try using flush() instead of close(). Also, I thought I was closing the socket before the user can read the file, but it didn't seem that was the case. Below I will have the Server.java code block and not the Client.java, cause it doesn't seem to be the problem.
Server.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
private static final int PORT = 9999;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server is listening on port " + PORT);
while (true) {
try (Socket socket = serverSocket.accept()) {
System.out.println("Client connected: " + socket);
new ClientHandler(socket).start();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static class ClientHandler extends Thread {
private Socket socket;
ClientHandler(Socket socket){
this.socket = socket;
}
#Override
public void run() {
try {
//Creating Sockets and Streams
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output));
while (socket.isConnected() && !socket.isClosed()) {
//Reading what the Client types
String request = reader.readLine();
//Split the values with "space" and store them in an array,
//then parse those values to two integers
String[] values = request.split(" ");
int A = Integer.parseInt(values[0]);
int B = Integer.parseInt(values[1]);
//Check if the pair in the file exists using checkPairInFile() method
boolean exists = checkPairInFile(A, B);
//if it does print 1 else 0
writer.println(exists ? "1" : "0");
//Flush the output to send the response back to the client
writer.flush();
}
//Print the disconnected user
System.out.println("Client disconnected: " + socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static boolean checkPairInFile(int A, int B) {
try (Scanner scanner = new Scanner(new File("edge_list.txt"))) {
//Scanning the file lines
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
//Split the values with "space"
String[] values = line.split(" ");
//Parse the values from String -> Int
int a = Integer.parseInt(values[0]);
int b = Integer.parseInt(values[1]);
//if both exist return true
if (A == a && B == b) {
return true;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
}
P.S. Thanks in advance for your help, in case this is problem with my Client.java file I will update the post.
This part:
try (Socket socket = serverSocket.accept()) {
System.out.println("Client connected: " + socket);
new ClientHandler(socket).start();
}
accepts a socket, then prints a message, then starts a new thread, then closes the socket. At some point later the new thread finishes starting up and tries to use the socket and realizes it was already closed.
try (...) {...} (officially called try-with-resources) always closes the things when it gets to the }. That's the point of it. If you don't want to close the socket at the } then you shouldn't use this type of statement.
I have a problem with the communication between a server and a client. I am trying to figure out a way of the communicating automatically because they have to exchange some parameters. However, with the code I wrote the server either keeps on sending the same message to the client after the client confirms the message or the client receives nothing at all. The sockets and everything have been setup up before. The function sendString() and receiveString() are identical inboth code examples. Is there a proper way of doing this? I dont get why this doesnt work...
Server:
String buffer;
while(true){
buffer = client.receiveString();
if(buffer != null && buffer.equals("ready")){
System.out.println("Client is ready");
client.sendString("ready");
while(true){
buffer = client.receiveString();
if(buffer != null && buffer.equals("k")){
System.out.println("stopped");
break;
}
}
break;
}
}
public String receiveString() throws IOException{ //From the client class
if(dataIn.available() > 0){
int length = dataIn.readInt();
byte[] b = new byte[length];
dataIn.readFully(b, 0, b.length);
return new String(b, Charset.forName("UTF-8"));
}
return null;
}
public void sendString(String msg) throws IOException{
byte[] b = msg.getBytes(Charset.forName("UTF-8"));
dataOut.writeInt(b.length);
dataOut.write(b);
}
Client:
String buffer;
while(true){
sendString("ready");
buffer = receiveString();
if(buffer!=null)
System.out.println(buffer);
if(buffer != null && buffer.equals("ready")){
System.out.println("Server is ready");
sendString("k");
break;
}
}
This code might work in your case:
Client.java
public class Client {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("localhost", 8080)) {
try (BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
Scanner in = new Scanner(socket.getInputStream())) {
System.out.println("Client: sending ready.");
writeLine("ready", out);
System.out.println("Client: sent ready.");
String line = in.nextLine();
if ("ready".equals(line)) {
System.out.println("Client: server is ready");
writeLine("k", out);
}
}
}
}
private static void writeLine(final String line, final BufferedOutputStream out) throws IOException {
out.write((line +"\n").getBytes());
out.flush();
}
}
Server.java:
public class Server {
public static void main(String[] args) throws Exception {
boolean running = true;
try (ServerSocket socket = new ServerSocket(8080, 0)) {
while (running) {
System.out.println("Waiting for client accept.");
try (final Socket client = socket.accept();
final Scanner in = new Scanner(client.getInputStream());
final BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream())) {
System.out.println("Waiting for client ready.");
String line = readLine(in);
if ("ready".equals(line)) {
writeLine("ready", out);
while (running) {
line = readLine(in);
if (line != null && line.equals("k")) {
System.out.println("Server: received stop signal");
running = false;
} else {
Thread.sleep(100);
System.out.println("Server: waiting for command.");
}
}
}
}
}
}
}
private static String readLine(final Scanner in) {
String line = in.nextLine();
System.out.println("Server: client sent " + line);
return line;
}
private static void writeLine(final String line, final BufferedOutputStream out) throws IOException {
out.write((line + "\n").getBytes());
out.flush();
}
}
So what is happening here?
Server socket waits for a client. If client connects, it waits for it to send something (in a blocking manner!). If its "ready", it checks for other commands.
Note: This only works for a single server<->client connection at a time. Dunno if this suites your application. The Server gets shutdown if client sends "k", like in your case.
I am currently coding a simple TCP chat client-server application which works with sockets. A client connects to the server and as soon as it gets accepted, a new worker thread is created to listen for client input. Connecting to the sever (localhost at port 8818) works fine, but as soon as the worker thread starts listening for more client input after the login a java.net.SocketException: Connection reset is thrown (see stack trace below). I am aware that one possible source of this exception can be a socket that hasn't been closed properly or forcefully by either the server or the client. Therefore, my assumption is that I am not handling the closing of my client socket properly which causes the connection to reset.
What I would like to achieve:
The worker listens for client input, as long as this is not null, requests (e.g. a simple login) are processed, otherwise, the socket is closed (see code excerpts below). My client receives a 'Login Successful' message from the server indicating that my handleLogin() function works, but instead of closing the socket after receiving no more input from the client, the server seems to just reset, even though clientSocket.close() is issued after the while loop.
Server.java
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(serverPort);
while (true) {
// Accept connection(s) from new chat client(s)
System.out.println("SERVER: WAITING TO ACCEPT CLIENT CONNECTIONS ...");
Socket clientSocket = serverSocket.accept();
System.out.println("SERVER: CONNECTION ACCEPTED FROM: " + clientSocket);
// Process client request in separate Thread
WorkerThread worker = new WorkerThread(this, clientSocket);
workerList.add(worker);
worker.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
WorkerThread.java
#Override
public void run() {
try {
handleClientSocket();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void handleLogin(OutputStream outputStream, String[] tokens) throws IOException {
if (tokens.length != 3) {
outputStream.write("LOGIN FAILED!\n".getBytes());
return;
}
// Extract username and password from user input
String username = tokens[1];
String password = tokens[2];
if (username.equals("anna") && password.equals("anna")) {
outputStream.write("Login successful!\n".getBytes());
} else {
outputStream.write("Error logging in!\n".getBytes());
}
}
private void handleClientSocket() throws IOException, InterruptedException {
InputStream inputStream = clientSocket.getInputStream();
this.outputStream = clientSocket.getOutputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
// THIS IS WHERE THE EXCEPTION OCCURS AFTER CLIENT HAS LOGGED IN SUCCESSFULLY
while ((line = bufferedReader.readLine()) != null) {
String[] tokens = StringUtils.split(line);
if (tokens.length > 0 && tokens != null) {
String command = tokens[0];
// Evaluate the entered command and handle the request accordingly
if ("login".equalsIgnoreCase(command)) {
handleLogin(outputStream, tokens);
}
// process other commands ...
}
}
clientSocket.close(); // POSSIBLY WORNG WAY OF CLOSING THE CLIENT SOCKET?
}
Client.java
import java.io.*;
import java.net.Socket;
public class Client {
private final String serverName;
private final int serverPort;
private Socket mySocket;
private OutputStream serverOut;
private InputStream serverIn;
public Client(String serverName, int serverPort) {
this.serverName = serverName;
this.serverPort = serverPort;
}
private boolean connect() {
try {
mySocket = new Socket(serverName, serverPort);
serverOut = mySocket.getOutputStream();
serverIn = mySocket.getInputStream();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void login(String username, String password) throws IOException {
String command = "login " + username + " " + password + "\n";
serverOut.write(command.getBytes());
}
public static void main(String[] args) throws IOException {
Client client = new Client("localhost", 8818);
if (client.connect()) {
System.out.println("Connection successful!");
client.login("anna", "anna");
} else {
System.err.println("Connection failed ...");
}
}
}
Stack Trace
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at WorkerThread.handleClientSocket(WorkerThread.java:70)
at WorkerThread.run(WorkerThread.java:45)
When I test my server with PUTTY (i.e. by connecting to localhost and then issuing commands in PUTTY's terminal), everything works just fine.
I am still fairly new to socket programming, so I also might have a logic flaw here. Any help will be much appreciated as I really would like to continue this project.
Thanks in advance!
The reason of this exception is that you terminated the client once you connected the server, but the server still read something from the stream. The exception occurs. Here is the code I tested:
while (inputStream.available() != 0) {
line = bufferedReader.readLine();
String[] tokens = StringUtils.split(line);
if (tokens.length > 0 && tokens != null) {
String command = tokens[0];
// Evaluate the entered command and handle the request accordingly
if ("login".equalsIgnoreCase(command)) {
handleLogin(outputStream, tokens);
}
// process other commands ...
}
}
change the condition in while loop to check if the inputstream is still available to read.
Hi I hope you guys are doing great.
I'm currently trying to test a service class that creates a socket connection to a print server.
Here's the service class :
public class PrintServiceImpl implements PrintService {
private static final Logger LOGGER = LoggerFactory.getLogger(PrintServiceImpl.class);
static final int TIMEOUT_MILLISECOND = 20000;
#Override
public boolean sendLabelToPrintServer(String hostname, int port, String labelData) {
Socket clientSocket = null;
DataOutputStream outToServer = null;
Boolean successful;
try {
// open the connection to the printing server
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(hostname, port), TIMEOUT_MILLISECOND);
clientSocket.setSoTimeout(TIMEOUT_MILLISECOND);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
// send data to print
outToServer.writeBytes(labelData);
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
StandardCharsets.UTF_8));
// Read HTTP Request CHARACTER BY CHARACTER instead of line by line
while ((char) input.read() != 0 && (char) input.read() != '\r') {
LOGGER.debug("Getting print server answer.");
}
successful = true;
LOGGER.debug("Label printed.");
} catch (Exception e) {
LOGGER.error("Printing failed.", e);
successful = false;
} finally {
try {
// close connection
if (outToServer != null) {
outToServer.close();
}
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) {
LOGGER.error("Exception while closing DataOutputStream/ClientSocket.", e);
}
}
return successful;
}
And here's my test class. As you can see the #Before method instantiates a SocketServer on a new Thread.
public class PrintServiceImplTest {
private static final Logger LOGGER = LoggerFactory.getLogger(PrintServiceImplTest.class);
PrintServiceImpl whfPrintService = new PrintServiceImpl();
private static final String LOCALHOST = "localhost";
private static final int SERVER_PORT = 3000;
private static final String LABEL_TEXT = "This dummy text is sent to the print server";
private static final String RESPONSE = "Test Label printed correctly";
private ServerSocket server;
private Socket incommingSocket = null;
#Before
public void before() {
Thread myThread = new Thread() {
#Override
public void run() {
try {
server = new ServerSocket(SERVER_PORT);
incommingSocket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
};
myThread.start();
}
#After
public void after() {
try {
incommingSocket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Test
public void returnsTrueIfConnectionSuccessful() {
BufferedReader reader = null;
PrintWriter out = null;
BufferedReader in = null;
String line;
whfPrintService.sendLabelToPrintServer(LOCALHOST, SERVER_PORT, LABEL_TEXT);
try {
in = new BufferedReader(new InputStreamReader(incommingSocket.getInputStream()));
out = new PrintWriter(incommingSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(incommingSocket.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println("line : " + line);
}
out.write(RESPONSE);
out.flush();
out.close();
in.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
When I run the test, I get a SocketTimoutException. It occurs when the client is reading the response from the server. This line :
while ((char) input.read() != 0 && (char) input.read() != '\r') {
So this means that the client does not receive a response. My guess is that the server does not send a correct response.
What am I missing ? thank you in advance.
Improper server->client response
You response doesn't end with a \0 or a \r.
private static final String RESPONSE = "Test Label printed correctly";
By making your response end with either of those characters, the client will escape from the loop.
private static final String RESPONSE = "Test Label printed correctly\0";
Client reads response incorrectly
The client reads the response using the following code:
while ((char) input.read() != 0 && (char) input.read() != '\r') {
Every call to input.read() returns a new byte from the network. You should call input.read() one time every while loop, and compare after it.
char c;
while (c = (char) input.read()) != -1) {
if(c == 0 || c == '\r') {
break;
}
}
Client to server message has no proper ending
Messages send from the client to server have no ending, the server reads until the socket input is closed, but the client never closes the socket.
// send data to print
outToServer.writeBytes(labelData);
After you wrote those bytes, call socket.shutdownOutput() to signal end of file to the other party.
// send data to print
outToServer.writeBytes(labelData);
clientSocket.shutdownOutput();
I've written some serverside socket handling code and I'm concerned that potentially my packets are not always making it back to the client. I am logging all my events and in my log files it says I am sending the information. But the client is also logging events and in their logs they say they do not receive anything.
My code to send the data is as follows:
public void write(Packet packet) {
String data = packet.serialize();
log("Send=[" + data + "]", "Write"); // log to file
try {
_writer.write(data);
_writer.flush();
} catch (Exception ex) {
log(ex, "write");
}
}
Each socket is created on a new thread and I create my writers and readers immediately like so (in the public run method):
// _sockt is a Java Socket object
_writer = new BufferedWriter(new OutputStreamWriter(_socket
.getOutputStream()));
_reader = new SocketReader(_socket);
SocketReader is just a wrapper class I created for listening for responses and has a public read method like so:
public String read() throws IOException, SocketTimeoutException {
_socket.setSoTimeout(_timeOut);
if(_reader == null)
_reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
// read from the stream
return new PacketDataInputStream(_reader).read();
}
The PacketDataInputStream wrapper class:
BufferedReader _reader = null;
public PacketDataInputStream(BufferedReader reader)
{
_reader = reader;
}
public String read() throws IOException, SocketException {
StringBuilder builder = new StringBuilder();
int c = 0;
while((c = _reader.read()) != -1)
{
char ch = (char)c;
builder.append(ch);
if(ch == PacketConstants.ETX)
break;
}
if(builder.length() > 0)
return builder.toString();
else
return null;
}
The way I'm creating the actual socket listener objects is pretty standard I think:
InetAddress address = InetAddress.getByName(IP);
server = new ServerSocket( port, 0, address);
// My own manager class to handle all the sockets connected
WebSocketManager manager = new WebSocketManager(this);
Socket connection = null;
while(bContinue)
{
connection = server.accept();
if(bContinue) {
// assign the socket to a new thread and start
// that thread
manager.newSocket(connection);
} else {
connection.close();
}
}
Is is possible that I'm using the wrong objects for sending the data back.
Should I even be using a bufferedwriter and reader? I had thought that these were the best way to go but now I'm not so sure.
It's important to note that this does not happen all the time, just sporadically. It could be the clients code having bugs but I need to make sure that I'm doing it correctly before going back to them.
This code is run on a Linux Ubuntu server. Logging occurs to a text file, nothing special there. My log files show the Send="" data going back to the client and no exception so it appears as if the .write and .flush() worked? Socket connections are persistant and only closed by the client and or network issues.
UPDATE ----- Client Side code -------:
I did manage to get some of the client side code for how they are handling the send and receiving of data (just in case it's more obvious on their end). The client is actually connecting to this server via an Android device (if that helps).
Creation of socket
static final int BUFFER_SIZE = 20000; // Maximum packet size
java.net.InetAddress server = java.net.InetAddress.getByName(url);
socket = new Socket(server, port);
// Set socket options:
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.setSendBufferSize(BUFFER_SIZE);
socket.setKeepAlive(true);
socket.setTcpNoDelay(true);
Sending:
try {
// Send the packet:
OutputStream stream = socket.getOutputStream();
stream.write(p.getByteArray ());
stream.flush();
// Update the time:
lastPacketSendTime = new Date ();
} catch (IOException e) {
setError("Error sending packet (" + e.getMessage() + ")", ERROR_IO);
return false;
}
Receiving:
socket.setSoTimeout(timeout);
// Get the reader:
inputStream = socket.getInputStream();
while (true) {
// Get the next character:
int value = inputStream.read();
// Check for -1, indicating that the socket is closed:
if (value == -1) {
// The socket is closed remotely, so close it locally as well:
disconnect();
inputStream = null;
return null;
}
// ... and a bunch of other stuff to handle the actual data
}
EDIT 14-Nov:
This is actually proving to be more of a problem now. Both the client logs and the server logs appear to be sending. But at times the data doesn't appear to come through or if it does it is sometimes coming through 10 - 30 - 60 second delayed.
I can provide more information if required.
When you use BufferedReaders and BufferedWriters things get buffered. How about using the input and output streams directly.. Also, writers are character based, I don't know if you need to send binary data but if so that will be a problem with writers.
I am not sure whether this will be to your any use or not.. but i am giving you the code i used for client server communication..
Client Side:
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket("127.0.0.1", 4444);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Server Code:
import java.io.*
import java.net.*;
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
#Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}