I want to send x object over socket but when I run this code i got nothings.
it is stop at new ObjectInputStream(socket.getInputStream())
and don't do any thing else.
Server class:
public class Server {
private static final int PORT = 9001;
ServerSocket listener;
private Handler h[] = new Handler[5];
private int clientCount = 0;
public Server() throws Exception{
System.out.println("The server is running.");
listener = new ServerSocket(PORT);
run();
}
public void run(){
while (true) {
try {
addClient(listener.accept());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void addClient(Socket socket) throws Exception{
h[clientCount] = new Handler(this, socket,clientCount);
h[clientCount].open();
clientCount++;
}
public static void main(String[] args) throws Exception {
Server s = new Server();
}
}
Handler class // Handle class:
public class Handler extends Thread {
private Server server;
private Socket socket;
private int ID = -1;
private ObjectInputStream obIn = null;
private ObjectOutputStream obOut = null;
public Handler(Server _server, Socket _socket, int i){
super();
server = _server;
socket = _socket;
ID = i;
}
public void open()
{
try {
obIn = new ObjectInputStream(socket.getInputStream());
obOut = new ObjectOutputStream(socket.getOutputStream());
x= ob.readObject();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The client:
public class Client {
ObjectInputStream oin;
ObjectOutputStream oot;
private Socket socket = null;
public Client() {
String serverAddress = "127.0.0.1";
try {
socket = new Socket(serverAddress, 9001);
oin = new ObjectInputStream(socket.getInputStream());
oot = new ObjectOutputStream(socket.getOutputStream());
System.out.println("hello i am a client");
oot.writeObject(x);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Client client = new Client();
}
}
You must declare the ObjectOutputStream before you declare the ObjectInputStream.
When you create an ObjectInputStream, it waits for data from an ObjectOutputStream. It's waiting on that data (the header).
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader(); //this is whats causing it to block
bin.setBlockDataMode(true);
}
protected void readStreamHeader() throws IOException, StreamCorruptedException {
short s0 = bin.readShort();
short s1 = bin.readShort();
if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
throw new StreamCorruptedException(String.format("invalid stream header: %04X%04X", s0, s1));
}
}
If you declare ObjectOutputStream first, it sends the data, which isn't blocking
Related
I'm not really good with Java and I wanted to write a simple client-server program (to date books) but I don't know how to share the variable termins between Threads (or where I made the mistake). Any advice would be accepted. I have been stuck on this for a few hours.
Here is my code:
Termin.java:
public class Termin {
public volatile int hour;
public volatile boolean reserved = false;
public volatile String user = null;
public Termin(int hour) {
this.hour = hour;
}
public void setHour(int value) {
this.hour = value;
}
...
Server.java:
public class Server {
public static final int PORT = 4444;
public volatile static Termin[] termins = new Termin[] {
new Termin(8),
new Termin(9),
new Termin(10),
new Termin(11),
new Termin(12),
new Termin(13),
new Termin(14),
new Termin(15),
new Termin(16),
new Termin(17),
};
public static void main(String[] args) throws IOException{
Server server = new Server();
server.runServer();
}
public void runServer() throws IOException{
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Server up and ready for connections...");
while(true){
Socket socket = serverSocket.accept();
new ServerThread(socket).start();
}
}
}
ServerThread.java:
public class ServerThread extends Thread {
Socket socket;
ServerThread(Socket socket){
this.socket = socket;
}
public void run(){
try {
String message = null;
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("user '" + bufferedReader.readLine() + "' is now connected to the server");
while ((message = bufferedReader.readLine()) != null) {
System.out.println("incoming client message: " + message);
printWriter.println(message);
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
How I connect Clint.java:
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException{
String name = args[0];
Socket socket = new Socket("localhost", Server.PORT);
BufferedReader bufferedReaderFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(name);
BufferedReader bufferedReaderFromCmdPrompt = new java.io.BufferedReader(new InputStreamReader(System.in));
And the fragment in Client.java where I change value of termins:
try {
String newReaderInput = bufferedReaderFromCmdPrompt.readLine();
printWriter.println(newReaderInput);
int var = Integer.parseInt(bufferedReaderFromClient.readLine());
if(var == 10 || var == 1 || var == 2 || var == 3 || var == 4 || var == 5 || var == 6 || var == 7 || var == 8 || var == 9 ) {
if(Server.termins[var].reserved == false) {
Server.termins[var-1].setReserved(true);
Server.termins[var-1].setUser(name);
System.out.println("\n\nTermin reserved.\n\n");
x=0;
} else {
System.out.println("\n\nError. Termin already booked\n\n");
}
} else {
System.out.println("\n\nError. No termin like this.!!!\n\n");
displayYourTermins(name);
}
} catch (NumberFormatException e) {
System.out.println("\n\nError. Write a number!!!\n\n");
displayYourTermins(name);
}
You can share variables between different threads via constructor of your-custom-thread class.
For Example,
Your Server.java want send object with ServerThread.java, You should pass this object as argument of constructor.
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static final int PORT = 4444;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(PORT);
try {
while(true) {
Socket socket = serverSocket.accept();
// Your Object that you want to share with another thread
Termin termin = new Termin(20);
// Pass objects in constructor of another thread, So that another thread can use it.
// If you want to share more than one object, then change constructor and pass it via constructor.
new ServerThread(socket, termin).start();
}
} catch(Exception e) {
System.out.println("Exception occurred in Server Program");
e.printStackTrace();
} finally {
serverSocket.close();
System.out.println("Server Program Ended");
}
}
}
If you want to use this object from ServerThread.java, You should save reference of that object and then you can use this object in another thread. For Example: ServerThread.java
public class ServerThread extends Thread {
private Socket socket;
private Termin termin;
public ServerThread(Socket socket, Termin termin) {
this.socket = socket;
this.termin = termin;
}
#Override
public void run() {
// Your logic...
// Here you can use termin which was passed from main thread.
// If you change termin object here, it will also affect termin object in main thread.
}
}
Here you can use termin and socket both which are shared between main-thread and ServerThread-thread.
I'm writing tests to test the health of the server and client side. In the test, I run the client side, through the creation of the socket, on port 3000. And ServerSocket I also specify port 3000. With normal deployment, everything works correctly. But the test falls apart
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:224)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at com.epam.preproduction.linnyk.server.factory.TCPServerTest.testGetCount(TCPServerTest.java:54)
My Server:
public abstract class Server implements Runnable {
protected ServerCommand serverCommandController;
private final Socket clientSocket;
public Server(Socket clientSocket) {
this.clientSocket = clientSocket;
serverCommandController = ApplicationContext.getServerCommandController();
}
#Override
public void run() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream()))) {
checkPortAndConnection(reader, output);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (!clientSocket.isConnected()) {
clientSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public class TCPServer extends Server {
public TCPServer(Socket clientSocket) {
super(clientSocket);
}
#Override
protected String getRequest(BufferedReader input) throws IOException {
return input.readLine();
}
#Override
protected void setResponse(BufferedWriter output, String request) throws IOException {
String result = serverCommandController.execute(RequestParser.tcpParserCommand(request));
output.write(result + "\n");
output.flush();
}
MyTest:
public class TCPServerTest {
private static StoreService productService;
private static Server serverSide;
private static Socket socket;
private static DataInputStream ois;
private static DataOutputStream oos;
#BeforeClass
public static void init() throws IOException {
Main main = new Main();
main.init();
productService = new StoreServiceImpl(new ProductRepositoryImpl());
socket = new Socket(InetAddress.getLocalHost(), 3000);
Runnable server = () -> {
serverSide = new TCPServer(socket);
try {
serverSide.run();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
};
new Thread(server).start();
ois = new DataInputStream(socket.getInputStream());
oos = new DataOutputStream(socket.getOutputStream());
}
#Test
public void testGetCount() throws IOException {
oos.writeUTF("get count");
oos.flush();
String response = ois.readUTF();
int count = productService.getProductMap().size();
String expectedCount = String.valueOf(count);
assertEquals(expectedCount, response);
}
#AfterClass
public static void tearDown() throws IOException {
oos.writeUTF("exit");
oos.flush();
socket.close();
}
I do not understand a bit where I could make a mistake. Can you tell me where the error in the test is? Thank you in advance)
Found an error that in this method to my request is added oos.writeUTF("get count"); /t how can it be removed?
I run this once with boolean "thisIsServer" true and other time false
but the method "message.ChangeA();" doesn't work
(the line System.out.println("message modified"); does't work)
this is main code:
public class Main{
static Semaphore lock = new Semaphore(0);
public static boolean thisIsServer = false;
public static final int port = 8888;
public static Semaphore Lock = new Semaphore(0);
public static Semaphore Lock2 = new Semaphore(0);
public static Message message;
public static String command = new String();
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
if(thisIsServer){
//This is Server
Thread server = new Server();
server.start();
while (true){
Lock.acquire();
message.changeA();
//Lock2.release();
System.out.println("message modified");
}
}else{
//This is Client
Socket socket = new Socket("localhost", port);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
os.writeObject(new Message(10));
while(true) {
Message returnMessage = (Message) is.readObject();
System.out.println("A is : " + returnMessage.a);
os.writeObject(returnMessage);
}
}
}
}
Server code :
public class Server extends Thread {
public static final int port = 8888;
#Override
public void run() {
//This is Server
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
while (true) {
Main.message = (Message) is.readObject();
System.out.println("message received");
Main.lock.release();
synchronized (this){
wait(1000);
}
System.out.println("message sent");
os.writeObject(Main.message);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
message code:
public class Message implements Serializable{
public Message(int a){
this.a = a;
}
public int a;
public void changeA(){
a = 2*a;
}
}
I think it's because you define Lock in two shape "Lock" and "lock".
But you have used Lock.acquire() for waiting and have used Main.lock.release() when you are unlocking in the thread.
My problem is that for some reason, whenever I want to pipe a string to the server console, the server receives nothing. I've tried to track it down with debugging, but I'm not able to find the issue. I passed a PrintWriter through from MCSERVERPROZESS to the SERVER Runnable and the string I want to pipe through is not null. Here are the codes:
public class MCSERVERPROZESS extends Thread {
private SERVERGUI servergui = null;
private SERVER server = null;
private String serverPath = "/home/mint/mc_server";
private ProcessBuilder builder = new ProcessBuilder("java", "-Xmx1024M", "-Xms1024M", "-jar", "server.jar", "nogui");
public MCSERVERPROZESS(SERVER server, SERVERGUI servergui) throws IOException {
this.servergui = servergui;
this.server = server;
}
#Override
public void run() {
try {
builder.directory(new File(serverPath));
final Process pr = builder.start();
OutputStream stdin = pr.getOutputStream();
InputStream stderr = pr.getErrorStream();
InputStream stdout = pr.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stdout));
this.server.setProcessOutputStream(new PrintWriter(stdin));
String serverOutputText;
do {
serverOutputText= in.readLine();
this.servergui.updateServerArea(serverOutputText+ "\n");
} while (serverOutputText.contains("Stopping server"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public class SERVER implements Runnable {
private SERVERGUI servergui = null;
private int port = 10001;
private ServerSocket serverSocket = null;
private BufferedReader in = null;
private PrintWriter out = null;
private MCSERVERPROZESS mcserver = null;
//private Socket clientSocket = null;
private ArrayList<CLIENTPROZESS> clients = new ArrayList<>();
public SERVER(int Port, SERVERGUI server) throws IOException {
this.servergui = server;
this.port = port;
}
public void run() {
try {
mcserver = new MCSERVERPROZESS(this, this.servergui);
mcserver.start();
servergui.setServer(this);
startServer();
} catch (IOException e) {
e.printStackTrace();
}
}
public void startServer() throws IOException {
this.serverSocket = new ServerSocket(port);
while(true) {
waitForConnection();
}
}
public void waitForConnection() throws IOException {
Socket clientSocket = serverSocket.accept();
this.startConnection(clientSocket);
}
public synchronized void startConnection(Socket s) throws IOException {
new CLIENTPROZESS(s, this).start();
}
void setProcessOutputStream(PrintWriter pw) {
this.out = pw;
}
void sendTextToConsole(String s) throws IOException {
out.write(s);
System.out.println(s);
}
SERVER.sendTextToConsole is used for piping through String to console.
I have a problem with a multi-connected server TCP. It accepts connection to client, but it stuck when it must read data (array of bytes[]) in InputBuffer.
The code is follow:
Server:
public class thread_acc extends Thread{
private final ServerSocket sock_acc;
public thread_acc() throws IOException {
this.sock_acc = new ServerSocket(10000);
}
#Override
public void run(){
for(;;){
try {
Socket sock_client = sock_acc.accept();
System.out.println("connection accepts");
new Thread(new thread_proc(sock_client)).start();
} catch (IOException ex) { Logger.getLogger(thread_acc.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class thread_proc implements Runnable{
private Socket sock_client;
public thread_proc(Socket sock){
this.sock_client = sock;
}
#Override
public void run(){
try {
procRequest();
} catch (IOException ex) {
Logger.getLogger(thread_proc.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(thread_proc.class.getName()).log(Level.SEVERE, null, ex);
}
}
void procRequest() throws IOException, ClassNotFoundException{
byte[] pack1 = socket.readSocket(sock_client);
System.out.println("read pack 1");
byte[] pack2 = socket.readSocket(sock_client);
System.out.println("read pack 2");
.....
}
Client:
public class thread_key implements Runnable {
private static InetAddress IpServer = InetAddress.getByName("127.0.0.1");
private static int PortServer = 10000;
private Socket sock_send;
private int id;
private String namefile;
public thread_key(int id, String namefile) throws IOException {
this.sock_send = new Socket(IpServer, PortServer);
this.id = id;
this.namefile = namefile;
}
#Override
public void run(){
Request();
}
private String[] Request(int iddoc) throws IOException, ClassNotFoundException{
...generations Keys RSA and payloads....
byte[] pack1 = RSA.encryptPub(payload1, pub);
byte[] pack2 = RSA.encryptPub(payload2, pub);
socket.writeSocket(sock_send, pack1);
socket.writeSocket(sock_send, pack2);
System.out.println("write ok");
}
}
Read and Write:
public class socket {
public static void writeSocket(Socket sock, byte[] pacchetto) throws IOException{
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject(pacchetto);
out.flush();
}
public static byte[] readSocket(Socket sock) throws IOException, ClassNotFoundException{
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
byte[] pacchetto = (byte[]) in.readObject();
return pacchetto;
}
}
Don't create new object streams every time you want to send or receive something. Use the same streams for the life of the socket, at both ends. Object streams have headers which are read or written on construction, so if construction at the receiver doesn't match construction at the sender, errors will ensue.