run server in a thread - java

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.

Related

Simple P2P server, object gets corrupted after being relayed from the server

Using
public class Server {
private static ServerSocket server;
private static int port = 9876;
private static Socket p1 = null;
private static Socket p2 = null;
public static void main(String args[]) {
System.out.println("[Server] Attempting to bind port " + port);
try {
server = new ServerSocket(port);
} catch (IOException err) {
err.printStackTrace();
System.exit(1);
}
new Thread(new Runnable() {
#Override
public void run() {
while(p1 == null) {
try {
System.out.println("[Server] Waiting for P1 to connect");
p1 = server.accept();
System.out.println("[Server] P1 has connected");
ObjectInputStream ois = new ObjectInputStream(p1.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(p1.getOutputStream());
while (p1.isConnected()) {
String message = (String) ois.readObject();
System.out.println("[Server] P1 sent '" + message + "'");
if (p2.isConnected()) {
ObjectOutputStream p2out = new ObjectOutputStream(p2.getOutputStream());
p2out.writeObject("[P1] " + message);
} else {
oos.writeObject("[Server] P2 is not connected");
}
}
System.out.println("[Server] P1 has disconnected");
p1 = null;
} catch (Exception err) {
if(err instanceof SocketException) {
System.out.println("[Server] P1 has disconnected");
p1 = null;
} else {
err.printStackTrace();
}
}
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
while(p2 == null) {
if(p1 != null) {
try {
System.out.println("[Server] Waiting for P2 to connect");
p2 = server.accept();
System.out.println("[Server] P2 has connected");
ObjectInputStream ois = new ObjectInputStream(p2.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(p2.getOutputStream());
while (p2.isConnected()) {
String message = (String) ois.readObject();
System.out.println("[Server] P2 sent '" + message + "'");
if (p1.isConnected()) {
ObjectOutputStream p1out = new ObjectOutputStream(p1.getOutputStream());
p1out.writeObject("[P2] " + message);
} else {
oos.writeObject("[Server] P1 is not connected");
}
}
System.out.println("[Server] P2 has disconnected");
p2 = null;
} catch (Exception err) {
if(err instanceof SocketException) {
System.out.println("[Server] P2 has disconnected");
p2 = null;
} else {
err.printStackTrace();
}
}
}
}
}
}).start();
}
}
and
public class Client {
static ObjectOutputStream oos = null;
static ObjectInputStream ois = null;
static int port = 9876;
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException, InterruptedException{
InetAddress host = InetAddress.getLocalHost();
Socket socket = new Socket(host.getHostName(), port);
System.out.println("[Client] Connection established with port " + port);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
new Thread(new Runnable() {
#Override
public void run() {
try {
Object o = ois.readObject();
if(o instanceof String) {
String msg = (String) o;
System.out.println(msg);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}).start();
Scanner s = new Scanner(System.in);
while(true) {
String msg = s.nextLine();
oos.writeObject(msg);
}
}
}
This P2P Server/Client is supposed to have 1 client send a message to the server, then relay that message to the other client. When a message is sent from one client, the server outputs [Server] P2 sent 'hello', but after relaying the message to the other client, the other client gets this exception:
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at me.aj4real.tutorial.p2pChatServer.Client$1.run(Client.java:25)
at java.lang.Thread.run(Unknown Source)
Line 25 is Object o = ois.readObject();
How does the object get corrupted after being relayed from the server?
What can I do to prevent the object from being corrupted?
Basically the problem is, you shouldn't create TWO ObjectOutputStream-s using the same underlying OutputStream. You should only create one object-output-stream for each socket, and reuse it.
So the error is caused by rows ObjectOutputStream p1out = .. and ObjectOutputStream p2out = ...
The AC code comes from a "serialzation header". If we look at the constructor public ObjectOutputStream(OutputStream out) :
public ObjectOutputStream(OutputStream out) throws IOException {
...
writeStreamHeader();
...
}
and writeStreamHeader is
/**
* Magic number that is written to the stream header.
*/
final static short STREAM_MAGIC = (short)0xaced;
...
protected void writeStreamHeader() throws IOException {
bout.writeShort(STREAM_MAGIC);
bout.writeShort(STREAM_VERSION);
}
So if two object-output-streams are created, the header will be written twice, causing the de-serialization error on the client side.
A slightly modified version of the Server (it handles disconnection differently, for illustration purpose).
package clientserver;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static ServerSocket server;
private static int port = 9876;
private static Socket p1 = null;
private static Socket p2 = null;
static ObjectInputStream ois1, ois2;
static ObjectOutputStream oos1, oos2;
public static void main(String args[]) throws Exception {
System.out.println("server listening on port=" + port);
server = new ServerSocket(port);
p1 = server.accept();
System.out.println("[Server] P1 has connected");
p2 = server.accept();
System.out.println("[Server] P2 has connected");
ois1 = new ObjectInputStream(p1.getInputStream());
oos1 = new ObjectOutputStream(p1.getOutputStream());
ois2 = new ObjectInputStream(p2.getInputStream());
oos2 = new ObjectOutputStream(p2.getOutputStream());
new Thread(new Runnable() {
#Override
public void run() {
try {
while (p1.isConnected()) {
String message = (String) ois1.readObject();
System.out.printf("[Server] P1 sent msg=[%s]%n", message);
if (p2.isConnected()) {
ObjectOutputStream p2out = oos2;
p2out.writeObject("[P1] " + message);
} else {
oos1.writeObject("[Server] P2 is not connected");
}
}
System.out.println("[Server] P1 has disconnected");
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
try {
while (p2.isConnected()) {
String message = (String) ois2.readObject();
System.out.printf("[Server] P2 sent msg=[%s]%n", message);
if (p1.isConnected()) {
ObjectOutputStream p1out = oos1;
p1out.writeObject("[P2] " + message);
} else {
oos2.writeObject("[Server] P1 is not connected");
}
}
System.out.println("[Server] P2 has disconnected");
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}).start();
}
}

OutputStreamWriter and InputStreamReader for a Socket in Java, What am I doing wrong?

Using Sockets in java,
public class Server {
private static ServerSocket server;
private static int port = 9876;
static Socket p1 = null;
static Socket p2 = null;
public static void main(String args[]) throws IOException, ClassNotFoundException{
server = new ServerSocket(port);
Thread p1t = new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println("[Server] Waiting for connection");
p1 = server.accept();
System.out.println("[Server] Client connected");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p1.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String msg = String.valueOf(in.readLine());
System.out.println(msg);
out.write(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
});
p1t.start();
}
}
and
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException, InterruptedException{
Socket socket = new Socket(InetAddress.getLocalHost().getHostName(), 9876);
if(socket.isConnected()) {
System.out.println("[Client] Connected");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
try {
System.out.println(in.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
while(true) {
Scanner s = new Scanner(System.in);
out.write(s.nextLine());
}
}
}
}
The client is supposed to send a message to the server, and the server is supposed to relay that message back to the client; but either the BufferedReader for Client and Server are not reading anything that is sent, or the BufferedWriter for Client and Server is not sending anything.
I've also tried manually sending text using out.write("test"); in both classes.
What am I doing wrong in this situation?

How to enable multiple clients to communicate with the server?

The problem am having is that am not sure how to enable multiple clients to communicate with the server through threading, i've attempted it but I think am doing something wrong. Any help will be appreciated.
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
ArrayList clientOutputStreams;
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
public ClientHandler(Socket clientSocket) {
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(
sock.getInputStream());
reader = new BufferedReader(isReader);
} catch (Exception x) {
}
}
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read" + message);
tellEveryone(message);
}
} catch (Exception x) {
}
}
}
public void go() {
clientOutputStreams = new ArrayList();
try {
ServerSocket serverSock = new ServerSocket(5000);
while (true) {
Socket clientSocket = serverSock.accept();
PrintWriter writer = new PrintWriter(
clientSocket.getOutputStream());
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
System.out.println("got a connection");
}
} catch (Exception x) {
}
}
public void tellEveryone(String message) {
Iterator it = clientOutputStreams.iterator();
while (it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
} catch (Exception x) {
}
}
}
public static void main(String[] args) {
new ChatServer().go();
}`enter code here`
}
To allow multiple client to connect to your server you need a server to be continually looking for a new client to connect to. This can be done like:
while(true) {
Socket socket = Ssocket.accept();
[YourSocketClass] connection = new [YourSocketClass](socket);
Thread thread = new Thread(connection);
thread.start();
}
This is probably also best done in a separate server java file that can run independent of the client.

Send object via socket

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

Java Socket Programing

Problem:
I have written one java socket server which send response when I send first message from the client to it. But I want to send one more message based on the first response. After the first response i am not getting any other response?
Here is the Server code:
public class SendSmsServerSocket {
private final static CxpsLogger logger = CxpsLogger.getLogger(SendSmsServerSocket.class);
SendSmsServerSocket(){
try {
new SeverSocketForSms(new ServerSocket(4330));
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static class SeverSocketForSms extends Thread {
private Socket socket;
private ServerSocket serversocket;
private volatile static boolean running = true;
public SeverSocketForSms(ServerSocket ssocket) throws IOException {
this.serversocket = ssocket;
start();
}
public void run() {
try{
while(running) {
this.socket = serversocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String msg = br.readLine();
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("inside SeverSocketForSms: msg received is : "+msg);
}
}
catch(Exception e){
e.printStackTrace();
}
catch(Throwable t) {
System.out.println("Caught " + t + "xmlServerThread - closing thread");
}
}
public static void shutdown() {
System.out.println("Stopping socket connection and thread");
try{
socket.close();
}catch (Exception e) {
e.printStackTrace();
}
running = false;
}
public static void main (String [] args){
try {
System.out.println("Starting sms server ----- Please press Enter Key to stop the server after receiving one message");
SendSmsServerSocket s=new SendSmsServerSocket();
new Scanner(System.in).nextLine();
SeverSocketForSms.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Once you have an incoming connection, you should delgate the responsibility for handling that incoming connection to another Thread, otherwise you will block your "accept" thread until the current connection is closed...
while (running) {
this.socket = serversocket.accept();
Thread thread = new Thread(new Handler(socket));
thread.start();
}
And the Handler
public class Handler implements Runnable {
private Socket socket;
public Handler(Socket socket){
this.socket = socket;
}
public void run() {
// You may need to add a repeat and exit clause here...
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String msg = br.readLine();
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("inside SeverSocketForSms: msg received is : " + msg);
}
}

Categories