I want to send multiple data type over socket.
I have that code:
when I create client, it generates public and private keys and sends the public to serve and the serve stores it.
when client wants to send message to another client, it gets his public key from the server to encrypt the message.
But when I run this code it freeze at client in dest_public_key=(PublicKey) oin.readObject()
Why it stop at here?
Why it doesn't read the PublicKey's object that the handler writes to it?
Is there any problems in streams?
public class Server {
private static final int PORT = 9001;
ServerSocket listener;
private Handler h[] = new Handler[5];
public PublicKey[] keys = new PublicKey[5];
private int clientCount = 0;
public Server() throws Exception{
System.out.println("The server is running.");
listener = new ServerSocket(PORT);
run();
}
public void run() throws Exception{
System.out.println("Waiting for a client ...");
while (true) { addClient(listener.accept());}
}
private void addClient(Socket socket) throws Exception{
h[clientCount] = new ServerHandler(this, socket,clientCount);
h[clientCount].open(clientCount);
h[clientCount].start();
clientCount++;
}
public void store(int id,PublicKey key){
keys[id]=key;}
public PublicKey getPublicKey(int id){
return keys[id]; }
public static void main(String[] args) throws Exception {
Server s = new Server();}
}
handle class
public class Handler extends Thread {
private Server server;
private Socket socket;
private int ID = -1;
private DataInputStream streamIn = null;
private DataOutputStream streamOut = null;
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 run()
{ while (true)
{ try
{
int dest=streamIn.readInt();
PublicKey dest_public_key=server.getPublicKey(dest);
obOut.writeObject(dest_public_key);
obOut.flush();}}
}
public void open(int i)
{
PublicKey publick = null;
try {
streamOut = new DataOutputStream(socket.getOutputStream());
streamIn = new DataInputStream(socket.getInputStream());
obOut = new ObjectOutputStream(socket.getOutputStream());
obIn = new ObjectInputStream(socket.getInputStream());
publick=(PublicKey)obIn.readObject();
server.store(ID,publick);
streamOut.writeInt(i);
streamOut.flush();
} catch (Exception e) {
e.printStackTrace();}
}}
client class
public class Client extends implements Runnable {
DataInputStream din;
DataOutputStream dot;
ObjectInputStream oin;
ObjectOutputStream oot;
public Client() {
try {
socket = new Socket(serverAddress, 9001);
din = new DataInputStream(socket.getInputStream());
dot = new DataOutputStream(socket.getOutputStream());
oot = new ObjectOutputStream(socket.getOutputStream());
oin = new ObjectInputStream(socket.getInputStream());
RSA.generateKey();
public_key=RSA.keys.getPublic();
private_key=RSA.keys.getPrivate();
oot.writeObject(public_key);
oot.flush();
int j =din.readInt(); // read number from server
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Client client = new Client();
PublicKey dest_public_key=null;
System.out.println("enter client that you would to send to it");
Scanner input = new Scanner( System.in );
int select = input.nextInt();
dot.writeInt(select);
dot.flush();
dest_public_key=(PublicKey) oin.readObject();
}
}
Related
I have written a simple multithreaded Server on which the two Clients can send Messages to the Server an the Server a Message to all the Clients at once. But I can't get it to work as intended.
I already tried it by putting a List of all PrintWriters in the Server class and then print the Message through each PrintWriter but this didn't work either.
public class Client
{
private static final String IP = "10.59.0.188";
private Socket clientSocket;
private PrintWriter toServer;
private BufferedReader fromServer;
private BufferedReader input;
private String serverMessage;
private String clientMessage;
private String name;
public static void main(String[] args) {
try {
new Client();
} catch (Exception e) {
System.err.println(e);
}
}
public Client() throws IOException {
input = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Name: ");
name = input.readLine();
openConnection();
toServer.println(name);
while (true) {
clientMessage = input.readLine();
toServer.println(clientMessage);
}
//closeConnection();
}
private void openConnection() throws IOException{
clientSocket = new Socket(IP, 6666);
toServer = new PrintWriter(clientSocket.getOutputStream(), true);
fromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
}
public class Server {
private ServerSocket serverSocket;
private BufferedReader input;
private Vector<ClientProcess> processList;
private int clientCount = 0;
private String serverMessage;
public static void main(String[] args) {
try {
new Server();
} catch (Exception e) {
System.err.println(e);
}
}
public Server() throws IOException {
startServer();
while (clientCount < 2) {
waitForNewClient();
}
for (ClientProcess clientProcess : processList) {
clientProcess.start();
System.out.println("Clientprocess started");
}
}
private void startServer() throws IOException {
processList = new Vector<>();
input = new BufferedReader(new InputStreamReader(System.in));
serverSocket = new ServerSocket(6666);
System.out.println("Server online");
}
private void waitForNewClient() throws IOException {
System.out.println("Waitin' for new Client...");
Socket clientSocket = serverSocket.accept();
ClientProcess clientProcess = new ClientProcess(clientSocket);
processList.add(clientProcess);
clientCount++;
}
}
public class ClientProcess extends Thread {
private Socket clientSocket;
private PrintWriter toClient;
private BufferedReader fromClient;
private String clientMessage;
private String serverMessage;
private String name;
private BufferedReader input;
public ClientProcess(Socket clientSocket) {
this.clientSocket = clientSocket;
input = new BufferedReader(new InputStreamReader(System.in));
}
#Override
public void run() {
try {
openClientConnection();
name = fromClient.readLine();
do {
clientMessage = fromClient.readLine();
System.out.println(name + ": " + clientMessage);
} while (true);
//closeClientConnection();
} catch (IOException e) {
System.err.println(e);
}
}
private void openClientConnection() throws IOException {
toClient = new PrintWriter(clientSocket.getOutputStream());
fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
serverMessage = "ServerMessageTest00";
toClient.println(serverMessage);
System.out.println("Client Connection Online");
}
}
In the ClientProcess you create a new PrintWriter.
From the javadoc:
Creates a new PrintWriter, without automatic line flushing, from anexisting OutputStream.
This means your toClient.println(...); is wrote to the server's output buffer but will not be send to the client because you miss the toClient.flush().
I have a server and a client the client already connects successfully to the server even if i start another client it connects successfully and here is my problem the clients can send data to the server (its basically only a string)the server gets the data of both clients but the clients only get their own data back and i would like to have that both clients get the same data from the server back.
Server:
public class Server extends Application {
#Override
public void start(Stage primaryStage) {
}
static ServerSocket serverSocket;
static Socket socket;
static DataOutputStream out;
static DataInputStream in;
static Users[] user = new Users[10];
public static void main(String[] args) throws IOException {
System.out.println("Starting server...");
serverSocket = new ServerSocket(7777);
System.out.println("Server started");
while(true){
socket = serverSocket.accept();
for(int i = 0;i < 10; i++){
System.out.println("Connection from:" + socket.getInetAddress());
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
if(user[i] == null){
user[i] = new Users(out,in,user);
Thread thread = new Thread(user[i]);
thread.start();
break;
}
}
}
}
private static class Users implements Runnable{
DataOutputStream out;
DataInputStream in;
Users[] user = new Users[10];
String name;
public Users(DataOutputStream out,DataInputStream in,Users[] user){
this.out = out;
this.in = in;
this.user = user;
}
#Override
public void run() {
while(true){
try {
String recievingData = in.readUTF();
System.out.println(recievingData);
out.writeUTF(recievingData);
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}}}
Client(both are the same):
public class ServerClient {
static Socket socket;
static DataInputStream in;
static DataOutputStream out;
public ServerClient() throws IOException{
System.out.println("Connecting");
socket = new Socket("localhost",7777);
System.out.println("Connecting succesful");
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
System.out.println("Recieving");
Input input = new Input(in);
Thread thread = new Thread(input);
thread.start();
}
public static void UploadPos(){
try {
out.writeUTF("TEST");
} catch (IOException ex) {
Logger.getLogger(ServerClient.class.getName()).log(Level.SEVERE, null, ex);
}
}}
class Input implements Runnable{
DataOutputStream out;
DataInputStream in;
public Input(DataInputStream in){
this.in = in;
}
#Override
public void run() {
while(true){
try {
String data = in.readUTF();
System.out.println(data);
} catch (IOException ex) {
Logger.getLogger(Input.class.getName()).log(Level.SEVERE, null, ex);
}
}
}}
Create a list of output streams.
List<DataOutputStream> clientOuts = new ArrayList<>();
after
out = new DataOutputStream(socket.getOutputStream());
add
clientOuts.add(out);
then replace
out.writeUTF(recievingData);
with
for(DataOutputStream cout :clientOutputs) {
cout.writeUTF(recievingData);
}
So I send a Server object to a client with this thread:
public ConnectionThread(final Server server) {
super(new Runnable() {
public void run() {
try {
Socket client = server.serverSocket.accept();
server.clients.add(client);
ObjectInputStream in = new ObjectInputStream(
client.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(
client.getOutputStream());
System.out.println("Connected client: "
+ client.getRemoteSocketAddress());
server.launchNewThread();
Object input;
while (!client.isClosed()) {
input = in.readObject();
if (input != null) {
if (input.toString().equals("server")) {
out.writeObject(server);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
And when I call out.writeObject(server) I get this exception:
java.io.NotSerializableException: java.net.Socket
Here is the Server class:
public class Server implements Serializable {
private static final long serialVersionUID = 4634111951586948020L;
public ServerArgs args;
public ArrayList<Socket> clients = new ArrayList<Socket>();
public ServerSocket serverSocket;
public Server(int port) throws IOException {
serverSocket = new ServerSocket(port);
launchNewThread();
}
public void launchNewThread() {
ConnectionThread thread = new ConnectionThread(this);
thread.start();
}
public static void main(String[] args) throws IOException {
new Server(27015);
}
}
public ArrayList<Socket> clients = new ArrayList<Socket>();
public ServerSocket serverSocket;
You have plenty of non-serializable sockets right there. It's very unclear what the purpose of "sending a server" is, but perhaps you should either just send the ServerArgs or mark those two fields transient.
I have a client/server connected over socket.
the client writes integer value to be read by the server
I use readInt() in ObjectOutputStream to write this value
and in the server side I use readInt() in ObjectInputStream to read this value.
But the server doesn't read any anything, it freeze at readInt()
What problem in reading using ObjectInputStream?
I was used DataOutputStream, and reading and writing was successful, but ObjectInputstream can read integer and other primitive type, what is the problem?
public class Server {
ServerSocket listener;
private static final int PORT = 9001;
private Socket socket;
private ObjectInputStream obin = null;
private ObjectOutputStream obout = null;
public Server() throws Exception{
listener = new ServerSocket(PORT);
run();
}
public void run() throws Exception{
socket = listener.accept();
obout = new ObjectOutputStream(socket.getOutputStream());
obout.flush();
obin = new ObjectInputStream(socket.getInputStream());
int h=obin.readInt();
System.out.println(h);
obout.writeInt(77);
}
public static void main(String[] args) throws Exception {
Server s = new Server();
}
}
and the client
public class Client {
private ObjectInputStream oin = null;
private ObjectOutputStream oot = null;
private Socket socket = null;
public Client() throws Exception{
String serverAddress = "127.0.0.1";
socket = new Socket(serverAddress, 9001);
oot = new ObjectOutputStream(socket.getOutputStream());
oot.flush();
oin = new ObjectInputStream(socket.getInputStream());
oot.writeInt(66);
int u = oin.readInt();
System.out.println(u);
}
public static void main(String[] args) throws Exception{
Client c= new Client();
}
}
When you run this code is supposed to get at the server 66
and at the client 77,
But actually I do not get anything. Why?
After every write you should flush() as it clears the output buffer which sends the bytes over the network. So your Server run method should be:
public void run() throws Exception {
socket = listener.accept();
obin = new ObjectInputStream(socket.getInputStream());
int h = obin.readInt();
System.out.println(h);
obout = new ObjectOutputStream(socket.getOutputStream());
obout.writeInt(77);
obout.flush();
}
and your Client constructor:
public Client() throws Exception {
String serverAddress = "127.0.0.1";
socket = new Socket(serverAddress, 9001);
oot = new ObjectOutputStream(socket.getOutputStream());
oot.writeInt(66);
oot.flush();
oin = new ObjectInputStream(socket.getInputStream());
int u = oin.readInt();
System.out.println(u);
}
If you're doing this as an exercise it's fine, but if you're going to run code based on this in production consider using higher level network libraries like protocol buffers.
I'm writing my first socket project and I have a problem. When the client sends a String to the server, the server can't get this message.
public class ClientActivity {
public static final String serverIP = "127.0.0.1";
private Socket clientSocket = null;
private static BufferedOutputStream out = null;
public static void main(String[] args) throws IOException {
ClientActivity me = new ClientActivity();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
out.write("Some string");
}
public ClientActivity() throws UnknownHostException, IOException {
clientSocket = new Socket(serverIP, serverPort);
out = new BufferedOutputStream(clientSocket.getOutputStream());
}
}
Here is the server's code:
public class DataTransferServer {
private ServerSocket serverSocket;
private ArrayList<DataReaderThread> workingThreads;
private Boolean isListening;
private Thread listener;
public static void main(String[] args) throws IOException {
new DataTransferServer(IProtocolConstants.SERVER_PORT).startServer(); // FIXME
}
public DataTransferServer (int port) throws IOException {
System.out.println("Launch");
serverSocket = new ServerSocket(port);
workingThreads = new ArrayList<DataReaderThread>();
isListening = true;
listener = new ConnectionListener();
}
public void startServer() throws IOException {
listener.start();
}
private class ConnectionListener extends Thread {
#Override
public void run() {
DataReaderThread newThread = null;
while (isListening) {
try {
newThread = new DataReaderThread(serverSocket.accept(), DataTransferServer.this);
newThread.start();
workingThreads.add(newThread);
System.out.println("! thread started");
} catch (IOException e) {
e.printStackTrace(); // FIXME
}
}
if (newThread != null) {
newThread.interrupt();
newThread = null;
}
}
}
}
And here is the listener:
public class DataReaderThread extends Thread {
private Socket socket = null;
private BufferedInputStream in = null;
private byte[] stuffBytes = null;
public DataReaderThread(Socket socket) throws IOException {
super("DataReaderThread");
this.socket = socket;
in = new BufferedInputStream(socket.getInputStream());
stuffBytes = new byte[10];
}
public void run() {
try {
while (in.read(stuffBytes, 0, stuffBytes.length) != -1) {
System.out.println("Received data:" + new String(stuffBytes));
}
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getSocket() {
return socket;
}
I guess the BufferedOutputStream out does not send a TCP packet until the buffer is full.
Try calling flush after write to send the data immediately:
out.write("Some string");
out.flush();
You may also consider using the PrintWriter class instead, which has an autoflush mechanism.
-1 Compile your code before posting...
public class ClientActivity {
public void write(String data) {
out.write(data.getBytes())
out.flush()
}
public static final String serverIP = "127.0.0.1";
private Socket clientSocket = null;
private BufferedOutputStream out = null;
public static void main(String[] args) throws IOException {
ClientActivity me = new ClientActivity();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
me.write("Some string");
}
public ClientActivity() throws UnknownHostException, IOException {
clientSocket = new Socket(serverIP, serverPort);
out = new BufferedOutputStream(clientSocket.getOutputStream());
}
}