I am currently implementing a multithreaded proxy server in java which will accept messages from clients and forward them to another server which will then acknowledge the reception of the message. However, i'm having trouble doing so. Could someone point out what i am doing wrong? Thanks.
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client{
public static void main(String[] args)
{
try
{
Socket client = new Socket(InetAddress.getLocalHost(), 6789);
if(client.isBound())
{
System.out.println("Successfully connected on port 6789");
}
Scanner scanner = new Scanner(System.in);
DataInputStream inFromProxy = new DataInputStream(client.getInputStream());
DataOutputStream outToProxy = new DataOutputStream(client.getOutputStream());
while(true)
{
String message;
System.out.print("Enter your message: ");
message = scanner.next();
outToProxy.writeUTF(message);
System.out.println(inFromProxy.readUTF());
}
}
catch(IOException io)
{
System.err.println("IOException: " + io.getMessage());
System.exit(2);
}
}
}
The server code Server.java:
import java.io.*;
import java.net.*;
/**
* the client send a String to the server the server returns it in UPPERCASE thats all
*/
public class Server {
public static void main(String[] args)
{
try
{
ServerSocket server = new ServerSocket(6780);
if(server.isBound())
{
System.out.println("Server successfully connected on port 6780");
}
Socket client = null;
while(true)
{
client = server.accept();
if(client.isConnected())
{
System.out.println("Proxy is connected");
}
DataInputStream inFromProxy = new DataInputStream(client.getInputStream());
DataOutputStream outToProxy = new DataOutputStream(client.getOutputStream());
System.out.println(inFromProxy.readUTF());
outToProxy.writeUTF("Message has been acknowledged!");
}
}
catch(IOException io)
{
System.err.println("IOException: " + io.getMessage());
System.exit(2);
}
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class Proxy{
public static ServerSocket server = null;
public static Socket client = null;
public static void main(String[] args)
{
try
{
server = new ServerSocket(6789);
Socket clientsocket = null;
while(true)
{
client = server.accept();
if(client.isConnected())
{
System.out.println("Proxy is currently listening to client on port 6789");
}
clientsocket = new Socket(InetAddress.getLocalHost(), 6780);
Thread t1 = new ProxyHandler(client, clientsocket);
t1.start();
if(clientsocket.isBound())
{
System.out.println("Clientsocket successfully connected on port 6780");
}
Thread t2 = new ProxyHandler(clientsocket, client);
t2.start();
}
}
catch(IOException io)
{
System.err.println("IOException: " + io.getMessage());
}
}
}
The Proxy code is:
import java.io.*;
import java.net.*;
public class ProxyHandler extends Thread {
private Socket socket;
private String message;
public ProxyHandler(Socket socket, Socket clientsocket)
{
this.socket = socket;
}
public void run()
{
message = "";
try
{
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
while(true)
{
message = in.readUTF();
out.writeUTF(message);
System.out.println(message);
}
}
catch(IOException io)
{
System.err.println("IOException: " + io.getMessage());
System.exit(2);
}
}
}
There is no multithreading here. There should be. Each accepted socket should be entirely processed in its own thread, in both the server and the proxy.
There is no point in testing isBound() immediately after creating and connecting a Socket. It will never be false.
There is no point in testing isConnected() immediately after an accept(). It will never be false.
The server must close each accepted socket once it is finished with it, i.e. once it has EOS from it (read() returns -1).
The proxy must also close each accepted socket once it is finished with it, ditto.
A proxy of any kind should just copy bytes. It shouldn't make assumptions about the format of the data. Don't use readUTF(), use count = read(byte[]) and write(buffer, 0, count). That also means that you don't need DataInput/OutputStreams in the proxy.
Related
I made a game similar to Flappy Bird by using JavaFX. Now I want to play it by using localhost IP.
How can I move the class in FlappyBird to the client so that the flappybird becomes the client?
also how can we make multiple clients using this?
This code is a simple one i made with simple concept behind it but what i don't understand is how can i make a class as in a game of flappy bird in the socket programming. How do i implement everything from the flappy bird to the client so the client becomes a flappy bird object
Client:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class FlappyClient
{
// initialize socket and input output streams
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream out = null;
// constructor to put ip address and port
public FlappyClient(String address, int port)
{
// establish a connection
try
{
socket = new Socket(address, port);
System.out.println("Connected");
// takes input from terminal
input = new DataInputStream(System.in);
// sends output to the socket
out = new DataOutputStream(socket.getOutputStream());
}
catch(UnknownHostException u)
{
System.out.println(u);
}
catch(IOException i)
{
System.out.println(i);
}
//=============
// close the connection
try
{
input.close();
out.close();
socket.close();
}
catch(IOException i)
{
System.out.println(i);
}
}
public static void main(String args[])
{
FlappyClient client = new FlappyClient("localhost", 5000);
}
}
````````````````````````````````````````````````
````````````````````````````````````````````````
public class FlappyServer
{
//initialize socket and input stream
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream in = null;
// constructor with port
public FlappyServer(int port)
{
// starts server and waits for a connection
try
{
server = new ServerSocket(port);
System.out.println("Server started");
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted");
// takes input from the client socket
in = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
String line = "";
// reads message from client until "Over" is sent
while (!line.equals("Over"))
{
try
{
line = in.readUTF();
System.out.println(line);
}
catch(IOException i)
{
System.out.println(i);
}
}
System.out.println("Closing connection");
// close connection
socket.close();
in.close();
}
catch(IOException i)
{
System.out.println(i);
}
}
public static void main(String args[])
{
FlappyServer server = new FlappyServer(5000);
}
}
`````````````````````````````````````````````
**The flappy bird class is too big. Lets call it FlappyBird I want to make this flappybird a client for the server**
I have found the answer
Main.main(null);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I have been "googeling" around for a long time for examples over Server-client-chat application, but I can't really understand them. Many of them are using a class and creates the GUI from it, and I don't want to copy straight from it. Alot of examples doesn't either really explain how you send messages from a client to the server and then it sends the message out to all the other clients.
I am using NetBeans and I was wondering if there is some good tutourials or examples that can help me with this?
Here comes the multiThreading program :) the server has two classes, and client has one. Hope you Like it!
SERVER MAIN CLASS:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
int MAXCLIENTS = 20;
int port = 4444;
ServerSocket server = null;
Socket clientSocket = null;
// An array of clientsConnected instances
ClientThread[] clientsConnected = new ClientThread[MAXCLIENTS];
try {
server = new ServerSocket(port);
System.out.println("listening on port: " + port);
} catch (IOException e) {// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
clientSocket = server.accept();
} catch (IOException e) {
e.printStackTrace();
if (!server.isClosed()){server.close();}
if (!clientSocket.isClosed()){clientSocket.close();}
}
System.out.println("Client connected!");
for (int c = 0; c < clientsConnected.length; c++){
if (clientsConnected[c] == null){
// if it is empty ( null) then start a new Thread, and pass the socket and the object of itself as parameter
(clientsConnected[c] = new ClientThread(clientSocket, clientsConnected)).start();
break; // have to break, else it will start 20 threads when the first client connects :P
}
}
}
}
}
SERVER CLIENT CLASS:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class ClientThread extends Thread{
private ClientThread[] clientsConnected;
private Socket socket = null;
private DataInputStream in = null;
private DataOutputStream out = null;
private String clientName = null;
//Constructor
public ClientThread(Socket socket, ClientThread[] clientsConnected){
this.socket = socket;
this.clientsConnected = clientsConnected;
}
public void run(){
try {
// Streams :)
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
String message = null;
clientName = in.readUTF();
while (true){
message = in.readUTF();
for (int c = 0; c < clientsConnected.length; c++){
if (clientsConnected[c]!= null && clientsConnected[c].clientName != this.clientName){ //dont send message to your self ;)
clientsConnected[c].sendMessage(message, clientName); // loops through all the list and calls the objects sendMessage method.
}
}
}
} catch (IOException e) {
System.out.println("Client disconnected!");
this.clientsConnected = null;
}
}
// Every instance of this class ( the client ) will have this method.
private void sendMessage(String mess, String name){
try {
out.writeUTF(name + " says: " + mess);
} catch (IOException e) {
e.printStackTrace();
}
}
}
AND FINALLY THE CLIENT:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws IOException {
Main m = new Main();
m.connect();
}
public void connect() throws IOException{
//declare a scanner so we can write a message
Scanner keyboard = new Scanner(System.in);
// localhost ip
String ip = "127.0.0.1";
int port = 4444;
Socket socket = null;
System.out.print("Enter your name: ");
String name = keyboard.nextLine();
try {
//connect
socket = new Socket(ip, port);
//initialize streams
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
//start a thread which will start listening for messages
new ReceiveMessage(in).start();
// send the name to the server!
out.writeUTF(name);
while (true){
//Write messages :)
String message = keyboard.nextLine();
out.writeUTF(message);
}
}
catch (IOException e){
e.printStackTrace();
if (!socket.isClosed()){socket.close();}
}
}
class ReceiveMessage extends Thread{
DataInputStream in;
ReceiveMessage(DataInputStream in){
this.in = in;
}
public void run(){
String message;
while (true){
try {
message = in.readUTF();
System.out.println(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I ran the server in eclipse, and started two clients from the CMD, looks like this:
Here is a super simple I made just now with some comments of what is going on. The client connects to the server can can type messages which the server will print out. This is not a chat program since the server receives messages, and the client send them. But hopefully you will understand better it better :)
Server:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static DataInputStream in;
public static DataOutputStream out;
public static void main(String[] args) throws IOException {
int port = 4444;
ServerSocket server = null;
Socket clientSocket = null;
try {
//start listening on port
server = new ServerSocket(port);
System.out.println("Listening on port: " + port);
//Accept client
clientSocket = server.accept();
System.out.println("client Connected!");
//initialize streams so we can send message
in = new DataInputStream(clientSocket.getInputStream());
out = new DataOutputStream(clientSocket.getOutputStream());
String message = null;
while (true) {
// as soon as a message is being received, print it out!
message = in.readUTF();
System.out.println(message);
}
}
catch (IOException e){
e.printStackTrace();
if (!server.isClosed()){server.close();}
if (!clientSocket.isClosed()){clientSocket.close();}
}
}
}
Client:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws IOException {
//declare a scanner so we can write a message
Scanner keyboard = new Scanner(System.in);
// localhost ip
String ip = "127.0.0.1";
int port = 4444;
Socket socket = null;
try {
//connect
socket = new Socket(ip, port);
//initialize streams
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
while (true){
System.out.print("\nMessage to server: ");
//Write a message :)
String message = keyboard.nextLine();
//Send it to the server which will just print it out
out.writeUTF(message);
}
}
catch (IOException e){
e.printStackTrace();
if (!socket.isClosed()){socket.close();}
}
}
}
I want that message sent by server should be delivered to all the clients however a message sent by by client should only be delivered to server.
Problem is when i run the code-
1.Server waits for client to connect
2.when multiple client connected
3.Now as the server broadcast the first message it is received by both the clients but when server broadcast the message second time. Both the clients has to send message in order to receive server message.
I am a noob in socket programming so please correct me what i am doing wrong?
So far i have made this program.
Server Code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
import java.net.*;
import java.io.*;
public class Server_Side3
{
static Client_server t[] = new Client_server[10];
static LinkedList<Client_server> al = new LinkedList<Client_server>();
public static void main(String args[]) throws IOException
{
ServerSocket server = null ;
Socket socket = null;
try
{
int Port =9777;
server = new ServerSocket(Port);
System.out.println("Waiting for Client " + server);
while(true)
{
socket = server.accept();
System.out.println("Connected to " + socket.getLocalAddress().getHostAddress());
Client_server clients = new Client_server(socket);
al.add(clients);
clients.start();
}
}
catch (Exception e)
{
System.out.println("An error occured.");
e.printStackTrace();
}
try
{
server.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static class Client_server extends Thread
{
Socket sockets;
PrintWriter out;
Client_server t[];
Client_server (Socket s )
{
sockets = s;
}
public void run()
{
try
{
InetAddress localaddr = InetAddress.getLocalHost();
Scanner sc = new Scanner(System.in);
Scanner in = new Scanner(sockets.getInputStream());
out = new PrintWriter(sockets.getOutputStream(),true);
String input = null;
while(true)
{
String servermsg = sc.nextLine();
broadcast(servermsg);
System.out.println("Message sent to client: "+servermsg);
input = in.nextLine();
System.out.println(localaddr.getHostName()+" Said :"+ input);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void broadcast(String servermsg)
{
Iterator it = al.iterator();
while(it.hasNext())
{
((Client_server) it.next()).send(servermsg);
}
}
private void send(String msg)
{
String servrmsg = msg;
out.println(msg);
out.flush();
}
}
}
Client Code :
import java.net.Socket;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientSide2
{
static Scanner chat = new Scanner(System.in);
public static void main(String[] args)
{
int Port = 9777;
String Host = "localhost";
try
{
Socket socket = new Socket(Host, Port);
System.out.println("You connected to "+ Host);
Scanner in = new Scanner(socket.getInputStream()); //GET THE CLIENTS INPUT STREAM
PrintWriter out = new PrintWriter(socket.getOutputStream());
String clientinput;
while(true)
{
System.out.println(in.nextLine());//If server has sent us something .Print it
clientinput=chat.nextLine();
out.println(clientinput); //SEND IT TO THE SERVER
out.flush();
}
}
catch (Exception e)
{
System.out.println("The server might not be up at this time.");
System.out.println("Please try again later.");
}
}
}
I've got a client and server coded in Java, once the server has received one message from the client, the server stops receiving all new messages. No errors are thrown when the client tries to sent more messages. I can't seem to find out why it doesn't allow or receive new connections! Please help.
public class Server implements Runnable {
#Override
public void run() {
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
boolean Listening = true;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
}
catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (Listening){
try {
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
//os = new PrintStream(clientSocket.getOutputStream());
// As long as we receive data, echo that data back to the client.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
while (true)
{
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
after accepting a connection it is entering into this infinite loop.due to this loop it will never accept new connection.
to solve this issues, start new thread each time when new client comes, pass socket connection of the client and read data from that client.
I see two issues as below:
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
Here you need to break after reading the content from the Socket irrespective of whether you read in different thread or same.
You need to declare boolean Listening to volatile else the server wont stop.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
the code will block new request, so the second request will not be accepted.
I make an example accounding to your code. Hope it help to you.
The Server Class will only be userd to accept socket connection and create a new thread to process it.
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server implements Runnable {
#Override
public void run() {
ServerSocket echoServer = null;
boolean listening = true;
Socket clientSocket = null;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
} catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (listening) {
try {
clientSocket = echoServer.accept();
System.out.println("receive new connection");
new ProcessClientThread(clientSocket).start();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
}
The ProcessClientThread Class extends Thread Class and defined a constructor with a Socket type parameter. Override run method of it. The run method get input stream from socket and print it out. When it accept 0, it will close the scoket connection. Its code like this
import java.io.DataInputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
public class ProcessClientThread extends Thread {
Socket socket = null;
public ProcessClientThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
DataInputStream is;
String line;
boolean flag = true;
try {
is = new DataInputStream(socket.getInputStream());
while (flag) {
line = is.readLine();
if (Integer.valueOf(line) != 0) {
// os.println(line);
// Logger.getLogger(Level.SEVERE,
// "New connection to server {0}", line);
System.out.println(line);
} else {
Writer w = new OutputStreamWriter(socket.getOutputStream());
w.write(0);
w.flush();
flag = false;
socket.close();
System.out.println("close a connection");
}
}
} catch(Exception e) {
}
}
}
There is a StartUp Class which used to start up the server thread.
public class StartUp {
public static void main(String[] args) {
new Thread(new Server()).start();
}
}
Run the below Client Class to test the Server.
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 9999);
OutputStreamWriter writer = new OutputStreamWriter(client.getOutputStream());
Reader reader = new InputStreamReader(System.in);
Reader serverReader = new InputStreamReader(client.getInputStream());
boolean flag = true;
while(flag) {
int readContent = reader.read();
writer.write(readContent);
writer.flush();
if(readContent == 0) {
writer.close();
client.close();
flag = false;
}
}
}
}
I'm trying to interconnect two socket clients connected to a single remote server.
The case is:
Client_1] connect to the server
Client_2] connect to the server
Server] create a tunnel between Client_1 and Client_2
Client_1] write "something"
Client_2] (that is waiting for some messages) receive "something" by Client_1
and viceversa.
That's my code:
package jtestsock;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
/**
*
* #author massimodeluisa
*/
public class Server extends Thread{
private List<Socket> clients;
private ServerSocket server;
private int port = 5001;
private BufferedReader input;
private PrintWriter output;
public Server() {
try {
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Impossibile istanziare il server: "+e.getMessage());
}
}
#Override
public void run() {
System.out.println("Waiting for client message...");
//
// The server do a loop here to accept all connection initiated by the
// client application.
//
while (true) {
try {
Socket socket = server.accept();
System.out.println("Connection Received!");
clients.add(socket);
/* read response */
input = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
output = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())));
if(clients.size()>0){
Socket first = new Socket();
Socket second = new Socket();
first = clients.get(1);
second= clients.get(2); // || second = socket;
// ??? Tunneling input and output between two clients
}
} catch (IOException e) {
System.out.println("Client connection error: "+e.getMessage());
}
}
}
}
Can anyone help me please?
Thanks :)
Update:
I would like to make a Point to Point connection between two clients, passing to my server, like a proxy server...
The server must accept more than two connection, and making two threads on the server for writing and reading that redirect messages from one client to the other, the CPU will be saturated.
(Ps. sorry for my English XD)
I would do it this way (simplified version):
class Server extends Thread
...
public void run() {
while (true) {
try {
Socket s1 = server.accept();
Socket s2 = server.accept();
new Client(s1, s2).start(); // reads from s1 and redirects to s2
new Client(s2, s1).start(); // reads from s2 and redirects to s1
} catch (IOException e) {
System.out.println("Client connection error: " + e.getMessage());
}
}
}
class Client extends Thread {
Socket s1;
Socket s2;
Client(Socket s1, Socket s2) {
this.s1 = s1;
this.s2 = s2;
}
public void run() {
try {
InputStream is = s1.getInputStream();
OutputStream os = s2.getOutputStream();
for (int i; (i = is.read()) != -1; i++) {
os.write(i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}