My server looks like this:
package marshexample;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.ServerSocket;
import java.net.Socket;
public class marshServer {
private ServerSocket ses;
private Reader br;
private OutputStream os;
public marshServer() {
StringBuilder sb = new StringBuilder();
try {
ses = new ServerSocket(7824);
Socket s = ses.accept();
br = new InputStreamReader(s.getInputStream());
char[] request = new char[6];
int count = br.read(request);
while (!sb.toString().contains("project")) {
sb.append(new String(request, 0, count));
count = br.read(request);
System.out.println(sb.toString());
}
System.out.println(sb);
os = s.getOutputStream();
os.write("string from server".getBytes());
os.write("empty line".getBytes());
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(sb);
}}
The issue is I have to add the string os.write("empty line".getBytes()); in order to make it work correctly. Without this string the massage is not fully sent to the client. (The same situation is with client). So why flush method does not solve this problem? Thank you for any ideas!
Related
I am new to Java just started yesterday. I wrote a very simple client server java code. Client sends a message to server. The Server should display that message. And the Server should send a message to client after receiving the message. The client should display the message sent by server.
Server Code,
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.net.Socket;
import java.net.ServerSocket;
public class CustomServer{
public static void main(String[] args){
final int SERVER_PORT_NUMBER = 8081;
try{
ServerSocket serverObj = new ServerSocket(SERVER_PORT_NUMBER);
Socket clientSocketObj = serverObj.accept();
BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocketObj.getInputStream()));
BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocketObj.getOutputStream()));
if(clientSocketObj != null){
System.out.println("Client Connected to Server!");
// Recieve Message from Client
System.out.println("MESSAGE FROM CLIENT");
System.out.println(clientInputStream.readLine());
// Send Message to Client
clientOutputStream.write("SERVER: Hello Client!");
// Close Streams
clientOutputStream.close();
clientInputStream.close();
}
serverObj.close();
}
catch(Exception e){
System.out.println(e);
}
}
}
Client,
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class CustomClient{
public static void main(String[] args){
final String HOST_NAME = "127.0.0.1";
final int SERVER_PORT_NUMBER = 8081;
try{
Socket clientSocket = new Socket(HOST_NAME, SERVER_PORT_NUMBER);
BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Connecting....");
if(clientSocket != null){
System.out.println("Connected to Server!");
// Send message to Server
clientOutputStream.write("CLIENT: HELLO SERVER");
// Recieve message from Server
System.out.println("MESSAGE FROM SERVER");
System.out.println(clientInputStream.readLine());
// Close Streams
clientInputStream.close();
clientOutputStream.close();
}
clientSocket.close();
}
catch(Exception e){
System.out.println(e);
}
}
}
Neither the Server or Client receive the message. Stuck in some loop. Anyone know why?
Start by having a read of the BufferedReader's JavaDocs, which state
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed
BufferedWriter#write is not sending this, so the reader is still waiting.
A simply solution might be to use BufferedWriter#newLine after the write
And don't forget to flush the buffer when you're finished writing to it!
You may also want to take a look at try-with-resources which will provide a better resource management solution
CustomClient
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class CustomClient {
public static void main(String[] args) {
final String HOST_NAME = "127.0.0.1";
final int SERVER_PORT_NUMBER = 8081;
try (Socket clientSocket = new Socket(HOST_NAME, SERVER_PORT_NUMBER)) {
try (BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
System.out.println("Connecting....");
System.out.println("Connected to Server!");
// Send message to Server
clientOutputStream.write("CLIENT: HELLO SERVER");
clientOutputStream.newLine();
clientOutputStream.flush();
// Recieve message from Server
System.out.println("MESSAGE FROM SERVER");
System.out.println(clientInputStream.readLine());
}
} catch (Exception e) {
System.out.println(e);
}
}
}
CustomServer
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class CustomServer {
public static void main(String[] args) {
final int SERVER_PORT_NUMBER = 8081;
try (ServerSocket serverObj = new ServerSocket(SERVER_PORT_NUMBER)) {
try (Socket clientSocketObj = serverObj.accept()) {
try (BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocketObj.getInputStream()));
BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocketObj.getOutputStream()))) {
System.out.println("Client Connected to Server!");
// Recieve Message from Client
System.out.println("MESSAGE FROM CLIENT");
System.out.println(clientInputStream.readLine());
// Send Message to Client
clientOutputStream.write("SERVER: Hello Client!");
clientOutputStream.newLine();
clientOutputStream.flush();
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
I have to make a chat application that is able to chat continuously back and forth between the server and the client. I have it so that the server and the client can send one message at a time, but I am not sure how to edit my code so that you can send multiple messages at a time. Also, I need to be able to run this on two separate computers, and I think I have my code set up accurately for this, but I am not sure. Verification for this and an answer to the first question would be appreciated. My code for each class is below.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ChatServer{
private ServerSocket serverSocket;
private Socket acceptSocket;
private PrintStream output;
private BufferedReader input;
private Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
ChatServer server = new ChatServer();
server.run();
}
public void run() {
try {
serverSocket = new ServerSocket(9999);
acceptSocket = serverSocket.accept();
output = new PrintStream(acceptSocket.getOutputStream());
input = new BufferedReader(new InputStreamReader(acceptSocket.getInputStream()));
while(acceptSocket.isConnected()) {
String message = input.readLine();
System.out.println(message);
String reply = scan.nextLine();
output.println(reply);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Scanner;
public class ChatClient{
private Socket clientSocket;
private BufferedReader input;
private PrintStream output;
private Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
ChatClient client = new ChatClient();
client.run();
}
public void run() {
try {
clientSocket = new Socket("127.0.0.1", 9999);
output = new PrintStream(clientSocket.getOutputStream());
output.println("Connected to Server");
input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(clientSocket.isConnected()) {
String message = input.readLine();
System.out.println(message);
String reply = scan.nextLine();
output.println(reply);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
SocketIO for Java is my suggestion. It does what you need it to in what will likely end up being less code and the documentation on it is superb with lots of examples. There is even an Android app demo that uses it for peer-to-peer chat.
https://github.com/socketio/socket.io-client-java
I am currently working on a project that will involve communication of applications written in C and Java. Therefore, I chose to work with Apache Avro. I have seen on the website that Avro can (de-)serialize objects from files using the DataFileWriter class.
But, in my case I want to use TCP sockets between my applications. Therefore, DataFileWriter class is not going to work for me. After reading the documentation, I have not found any information on how to send objects through TCP sockets.
Any ideas on how to do that? I specifically want to know what kind of Input and Output Streams I should use on the Java Clients.
I have developed the following code for the Java Server:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import middleman.bigpeer.BigPeer;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.io.BinaryDecoder;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
public class MiddleManWorker implements Runnable {
private InputStream in;
private OutputStream out;
private Socket clientSocket;
public MiddleManWorker(Socket clientSocket, HashMap<Integer, NodeType> dbNodesDirectory,
HashMap<Integer, NodeType> workersDirectory) {
this.clientSocket = clientSocket;
try {
this.in = clientSocket.getInputStream();
this.out = clientSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
EncoderFactory encoderFactory = new EncoderFactory();
DecoderFactory decoderFactory = new DecoderFactory();
BinaryEncoder binaryEncoder = encoderFactory.binaryEncoder(out, null);
BinaryDecoder binaryDecoder = decoderFactory.binaryDecoder(in, null);
SpecificDatumReader<BigPeer> peerDatumReader = new SpecificDatumReader<BigPeer>(BigPeer.class);
BigPeer bigPeer = null;
SpecificDatumWriter<BigPeer> writer = new SpecificDatumWriter<BigPeer>();
try {
peerDatumReader.read(bigPeer, binaryDecoder);
System.out.println("Received: " + bigPeer.getType());
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.write(bigPeer, binaryEncoder);
} catch (IOException e) {
e.printStackTrace();
}
}
}
A sample Java Client is the following:
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import middleman.bigpeer.BigPeer;
import org.apache.avro.io.BinaryDecoder;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
public class SystemClient {
public static void connect(String serverIPAddress, Integer serverPort) throws IOException, ClassNotFoundException {
/**
* Create Connection with the server
*/
Socket socket = new Socket(serverIPAddress, serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
EncoderFactory encoderFactory = new EncoderFactory();
DecoderFactory decoderFactory = new DecoderFactory();
BinaryEncoder binaryEncoder = encoderFactory.binaryEncoder(out, null);
BinaryDecoder binaryDecoder = decoderFactory.binaryDecoder(in, null);
BigPeer bigPeer = new BigPeer();
bigPeer.setType("test");
SpecificDatumReader<BigPeer> reader = new SpecificDatumReader<BigPeer>(BigPeer.class);
SpecificDatumWriter<BigPeer> writer = new SpecificDatumWriter<BigPeer>(BigPeer.class);
System.out.println("Before: " + bigPeer.getType());
writer.write(bigPeer, binaryEncoder);
System.out.println("Waiting for response...");
reader.read(bigPeer, binaryDecoder);
System.out.println("After: " + bigPeer.getType());
}
}
And the server seems to halt on the peerDatumReader.read(bigPeer, binaryDecoder); line of code. Any ideas?
Thank you,
Nick
BinaryEncoder uses an internal buffer for performance reasons. You may need to call flush on the encoder to send the data through the pipe.
See the reference for more information on this behaviour:
The BinaryEncoder implementation returned may buffer its output. Data may not appear on the underlying OutputStream until Flushable.flush() is called. The buffer size is configured with configureBufferSize(int).
If buffering is not desired, and lower performance is acceptable, use directBinaryEncoder(OutputStream, BinaryEncoder)
I've made a server that should let the client udpate a file. All in all it is working, but some bytes, for example HEX 9D is getting to HEX 3F. I have no more ideas and didn't find anything on the web. My server code:
package de;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class UpdateThread extends Thread {
public UpdateThread(Socket s) {
socket = s;
}
public void run() {
try {
execute();
} catch (IOException e) {
e.printStackTrace();
}
}
#SuppressWarnings("resource")
public void execute() throws IOException {
if (UpdateProvider.update) {
int i = 0;
SocketTools.sendData(1, socket);
File file = new File("." + System.getProperty("file.separator").toString() + "update_package.jar");
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
FileReader reader = new FileReader(file);
while ((i = reader.read()) != -1) {
writer.write(i);
}
writer.flush();
writer.close();
} else {
SocketTools.sendData(0, socket);
}
}
private Socket socket;
}
And my client code:
package de;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Main {
#SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
Socket s = new Socket("localhost", 16642);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
//InputStreamReader reader = new InputStreamReader(s.getInputStream());
int i = 0;
FileWriter writer = new FileWriter(new File("C:\\update_package.jar"));
int state = reader.read();
if (state == 48) {
System.exit(0);
}
if (state == 49) {
while ((i = reader.read()) != -1) {
System.out.println(i);
writer.write(i);
}
System.out.println("ENDE");
writer.flush();
}
}
}
You're not specifying a proper encoding for the transmission (you should use InputStream/OutputStreams instead of Reader/Writer for this anyways, since you're handling binary data and not text). 0x3F is the questionmark '?', meaning that a non-ASCII character (128 or higher) has been converted.
So lose the Readers and Writers and go with Streams.
Encoding is needed for text files only. I looked at your source code. You are trasferring a jar, which is a binary file, not text. If you use use text processing classes for binary data, you can get a lot of unpredictable transformations. Don't use OutputStreamWriter. Use socket.getOutputStream() directly:
OutputStream = socket.getOutputStream();
...
out.write(...);
Same for client. Don't use InputStreamReader. Use s.getInputStream() directly:
InputStream in = s.getInputStream();
...
in.read(...);
I am trying to serialize an object in a HttpHandler class.
I have 2 files, Server3.java:
package server3;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Server3 {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(3333), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
String response = "Kjo eshte nje pergjigje nga serveri! n";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
Personat obj = new Personat();
ObjectOutputStream objOut = new ObjectOutputStream(t.getResponseBody());
objOut.writeObject(obj);
objOut.close();
}
}
}
class Personat implements Serializable{
private static final long serialVersionUID = 1L;
int ID=3;
String Name="Andi";
}
and Client3.java:
package server3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
//te gjithe personat qe jan ne database me nej objekt
public class Client3 {
public static void main(String[] args) throws Exception {
try {
URL url = new URL("http://localhost:3333");
HttpURLConnection s = (HttpURLConnection) url.openConnection();
s.setDoOutput(true);
s.setDoInput(true);
s.setRequestMethod("POST");
s.setUseCaches(false);
InputStream in = s.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
int c;
while ((c = br.read()) != -1) {
System.out.print((char) c);
}
ObjectInputStream ios = new ObjectInputStream(s.getInputStream());
Personat oin = (Personat) ios.readObject();
String emri=oin.Name;
System.out.println(emri);
ios.close();
s.disconnect();
} catch (IOException ex) {
System.err.println(ex);
System.out.print(ex);
}
}
}
But when I run it eclipse shows me
java.io.EOFException Kjo eshte nje pergjigje nga serveri! njava.io.EOFException`
and I cant understand why.
The problem is that you are trying to fit both the string response and the object into response.length() bytes. What happens is that only response.length() bytes are sent and so if you try to read more you get the EOFException.
If you instead set the responseLength parameter to be 0 it will allow you to transmit an arbitrary amount of data
t.sendResponseHeaders(200, 0);
You also shouldn't close the stream if you are going to write more data into it. Don't call os.close() until all the writing is complete.