i am creating a simple client/server app
and was able to connect multiple clients to single server.
i referred to this link client/server simple app demo
my problem is that now,i want to return some response from server to client
based on its client/ip address.
eg. if 192.123.1.1 connects the response should be xml
if 192.123.1.2 connects the response should be json.
is it possible to do?? any help will be appreciated
here is my simple server code:
public class ChatServer implements Runnable
{
private ServerSocket server = null;
private Thread thread = null;
private ChatServerThread client = null;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start();
}
catch(IOException ioe)
{ System.out.println(ioe); }
}
public void run()
{ while (thread != null)
{ try
{ System.out.println("Waiting for a client ...");
addThread(server.accept());
}
catch(IOException ie)
{ System.out.println("Acceptance Error: " + ie); }
}
}
public void addThread(Socket socket)
{ System.out.println("Client accepted: " + socket);
client = new ChatServerThread(this, socket);
try
{ client.open();
client.start();
}
catch(IOException ioe)
{ System.out.println("Error opening thread: " + ioe); }
}
public void start()
public void stop()
public static void main(String args[])
I think instead of ip check the client should ask for the type of data they want. I am not sure why you require a check on ip. But in future if you all more clients then you have to change the server code every time. Better to define the format in the client so that client can ask for data of specific type.
Not very sure about your requirement.
There is an API call Socket.getRemoteSocketAddress().toString() to get the caller IP
Socket clientSocket =server.accept();
System.out.println(" client ip address =" +clientSocket.getRemoteSocketAddress().toString());
-- once you obtained clientSocket, use below sample to write back
Socket clientSocket =server.accept();
String returMessage ="Hello from Server ";
if (clientSocket.getRemoteSocketAddress().toString().equals("192.168.1.3")){
returMessage=returMessage +" welcome browser";
}
else if(clientSocket.getRemoteSocketAddress().toString().equals("192.168.1.4")){
returMessage=returMessage +" welcome tablet";
}
OutputStream os = clientSocket .getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returMessage);
System.out.println("Message sent to the client is "+returMessage);
bw.flush();
-- To read from client
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();
System.out.println("Message received from client is "+data);
if("send_players".equals(data)){ // reading data you would need to finetune
//write playerlist
}
Related
I'm an amateur in java socket programming. As I say in title, When I using PrintStream for socket output,it works;but it doesn't work if I using simply OutputStream.
I know the the client connected to the server cause' the server got the info of the client.So I think there must be something wrong with I/O stream, not the socket connection.
btw, I even use the flush() method for OutputStream.I think flush() will force to send all bytes, but it seems like it didn't work.
The Client Code:#line 12:
public class Clinet {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("==========Client============");
Socket socket = new Socket("localhost", 8888);// Server's addr and port
socket.setSoTimeout(3000);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
String msgToSent = "Hello TCP";
outputStream.write(msgToSent.getBytes());
outputStream.flush();// FIXME:why flush() didn't work?why msg wasn't sent.
// read from socket input
String receivedMsg = new String(inputStream.readAllBytes());
System.out.println(receivedMsg);
socket.close();
}
}
When I using a filter stream like PrintStream,the msg can be sent to server.
The Server Code: if using PrintStream it will work perfectly with the Client:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket client = serverSocket.accept();
new Thread(new ServerHandler(client)).start();
}
}
}
class ServerHandler implements Runnable {
private Socket client;
ServerHandler(Socket client) {
this.client = client;
}
#Override
public void run() {
try {
InetAddress clientAddr = client.getInetAddress();
int clientPort = client.getPort();
System.out.println("client connected # " + clientAddr + ":" + clientPort);
InputStream inputStream = client.getInputStream();
OutputStream outputStream = client.getOutputStream();
while (true) {
String msg = new String(inputStream.readAllBytes());// FIXME: Why Server didn't receive Client's msg?
System.out.print("/" + clientAddr + "#" + clientPort + " : ");
System.out.println(msg);
String reply = "I received " + msg.length() + " words.";// return how many words the server got.
outputStream.write(reply.getBytes());
outputStream.flush();// flush to ensure send all msg,but seems doesn't work
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am trying to open a socket inside a bukkit plugin so i could send data to it using php or node but instead of socket remaining open after one use it just closes and also server does not load before this happens what should i do i am out of ideas.
Main:
public class Main extends JavaPlugin {
public void onEnable() {
saveDefaultConfig();
getConfig().options().copyDefaults(true);
System.out.println("[INFO] Main class loaded.");
start();
}
public void start() {
SocketServer server = new SocketServer();
try {
server.start(getConfig().getInt("port"), getConfig().getString("socket-password"));
System.out.println("[INFO] Main successfully called start.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Socket server class:
When called this should read information convert it into array check the first item in array and use it as auth code then array should be converted into string and used in Command executor class. This works fine but after one use this just closes
public class SocketServer {
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void start(int port, String socketpwd) throws IOException {
System.out.println("[INFO] Socket server listening on: " + port);
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Boolean enabled = true;
try {
// Socket authentication
String message = in.readLine();
String suffix[] = message.split(" ");
System.out.println("Socket auth code used: "+ suffix[0]);
System.out.println("Socket pwd is: " + socketpwd);
if (socketpwd.equals(suffix[0])) {
out.println("Auth sucessfull!");
// do the following command from args here
String command = suffix[1];
int suffixL = suffix.length;
// add arguments to command
for (int i = 2; i < suffixL; i++) {
command = command + " " + suffix[i];
}
// call req exec
System.out.println("[INFO] Socket server contacted Request executor with: " + command);
RequestExecutor.executor(command);
enabled = false;
}
else {
out.println("Unrecognised auth code!");
}
} catch (NullPointerException e) {
System.out.println("Exception prevented!");
}
}
public void stop() throws IOException {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
}
Other problem as i mentioned is that bukkit server does not fully load before one request has been made to this socket.
Thank you for your help.
First of all you shouldn't be running a socket like that on the main thread, typically you should be running this on an async task using the Bukkit scheduler.
Then once you open the socket you should create a while loop to continuously poll for a connection and handle the incoming data. Instead what you are doing is opening the socket, reading a line and then dropping the connection.
You want to be doing something similar to
while(true){
Socket socket = serverSocket.accept();
}
See this webpage for some more info.
I'm having the following TCP client code:
public static void register(InetAddress ip, int port, String name) {
try {
Socket clientSocket = new Socket(ip, port);
send("reg:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void send(String str) {
try {
String sentence = str;
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(sentence);
} catch (IOException e) {
Log.e("CONNECT", e.getMessage());
}
}
They both are called in onClicks and i know that for sure.
I also have the following Server code:
public static void main(String argv[]) throws Exception {
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(9876);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
outToClient.writeBytes("msg: Hello! kalin pedro");
}
}
When trying to send data to the server i don't get an exception, i also know that I'm connected to it because the application is crashing when i terminate the server application. The problem is that the server doesn't receive anything until i terminate the client application. Everything that i have tried to send until that moment is all received from the server at once. I looked at the network activity tab provided by Android Studio and there is a change when sending data, the server just doesn't receive it(or at least i don't see it receive it) until i terminate the client application.
I'm new with Java and I'm trying to learn threads and socket. So decide to make simple client-server application following official java tutorial. My idea is simple - server wait for connection, if appears, it makes new thread with new socket, input and output. Client side -> make connection; new thread with socket, input, output and stdIn (to read line and after that send it to the server). But something is wrong (don't have any idea why) with my code. The connection is established, there's no exceptions. Could someone explain why doesn't work and how to fix it? Also could you have any suggestions about the code (probably it's not with best practices and things like that):
Client side:
public class Client {
private BufferedReader reader;
private Socket sock;
private PrintWriter writer;
public static void main(String[] args) {
Client client = new Client();
client.go();
}
public void go() {
setUpNetworking();
}
private void setUpNetworking() {
try{
sock = new Socket("127.0.0.1", 5000);
System.out.println("Network established");
ServerThread serverThread= new ServerThread(sock);
serverThread.start();
System.out.println("Type your message: ");
} catch (IOException e) {
System.out.println("Problem with establishing the network: " + e);
}
}
class ServerThread extends Thread {
Socket socket;
PrintWriter out;
BufferedReader in;
BufferedReader stdIn;
ServerThread(Socket socket) {
this.socket = socket;
try{
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
}catch (IOException e) {
System.out.println("Problem with trying to read/write to server: " + e);
}
}
#Override
public void run() {
String fromServer;
String fromClient;
while(true){
try{
if((fromServer = in.readLine()) != null) System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null) out.println(fromClient);
}catch(Exception e) {
System.out.println("msg exception: " + e);
}
}
}
}
}
Server side:
public class Server {
//Run server until keepGoing = false
private boolean keepGoing = true;
public static void main(String[] args) {
Server server = new Server();
server.go();
}
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while(keepGoing) {
Socket clientSocket = serverSocket.accept();
ClientThread t = new ClientThread(clientSocket);
t.start();
}
} catch (IOException e) {
System.out.println("Problem with socket/network: " + e);
}
}
class ClientThread extends Thread {
Socket clientSocket;
PrintWriter out;
BufferedReader in;
ClientThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try{
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
System.out.println("Problem with creating in/out: " + e);
}
}
#Override
public void run() {
String message;
while(keepGoing) {
try{
message = in.readLine();
out.println(message);
System.out.println(message);
} catch (IOException e){
System.out.println("Exception while try to read line: " + e);
}
}
}
}
}
PS I've changed a bit the code - instead of made ClientThread Class, I made new runnable class and pass that variable to thread class. Inspired by this question: "implements Runnable" vs. "extends Thread".
I think the problem is that both server and client are waiting for any input. Server:
message = in.readLine();
Client:
if((fromServer = in.readLine()) != null)
System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null)
out.println(fromClient);
But the client code already blocks on the fromServer = in.readLine() part, so it never gets to read from standard in, and thus nothing will be sent out to the server.
You could move your attempt to read from standard in to the setUpNetworking method, right after the System.out.println("Type your message: ");. Build a loop there which you exit if the user types "exit" or "quit" or something like that:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String read = "";
do {
read = stdIn.readLine();
System.out.println("Read from stdin: " + read);
serverThread.send(read);
}
while (!read.equals("exit"));
The ServerThread.send() method is simple:
void send(String string) {
System.out.println("Sending to server: " + string);
out.println(string);
}
However, to make it work, you either have to flush the stream manually after writing to out, or use the following constructor:
out = new PrintWriter(socket.getOutputStream(), true);
See the PrintWriter's JavaDoc: True means auto-flush on newline.
I tested this setup and it worked for me. I was able to send something from the client to the server.
However, this is only the first step. I would implement both reading and writing as separate threads, for both client and server. And there is no graceful shutdown of sockets implemenented yet. A more complete yet simple example can be found on Oracle.
I'm trying to write a simple chat program with a server and a single client. I can connect them together just fine with port forwarding and they can each receive a single message. However, once they connect, I want to to be able to send and receive messages at the same time. For some reason this isn't happening at all. Here's my code.
Client:
// Client class
public class Client
{
public static void main(String [] args)
{
// Get server name, port number, and username from command line
String serverName = args[0];
int port = Integer.parseInt(args[1]);
String username = args[2];
try
{
// Print welcome message and information
System.out.println("Hello, " + username);
System.out.println("Connecting to " + serverName + " on port " + port);
// Create the socket
Socket client = new Socket(serverName, port);
// Print connected information
System.out.println("Just connected to " + client.getRemoteSocketAddress());
// Out to server
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
// Print message to server
out.writeUTF("Hello from " + client.getLocalSocketAddress());
// In from server
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
// Print message from server
System.out.println("Server says " + in.readUTF());
// Begin reading user input to send to the server
Scanner chat = new Scanner(System.in);
String lineTo;
String lineFrom;
// Keep the program open unless the user types endchat
while (!chat.nextLine().equals("endchat"))
{
// Read any messages coming in from the server
lineFrom = String.valueOf(in.readUTF());
System.out.println(lineFrom);
// Write any messages to the client
lineTo = chat.nextLine();
out.writeUTF(lineTo);
}
// Close the connection
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Server:
// Server class
public class Server extends Thread
{
private ServerSocket serverSocket;
private String username;
// Create server
public Server(int port, String username) throws IOException
{
serverSocket = new ServerSocket(port);
this.username = username;
}
// Keep running
public void run()
{
try
{
// Print info
System.out.println("Hello, " + username);
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
// Accept the client
Socket server = serverSocket.accept();
// To client
OutputStream outToClient = server.getOutputStream();
DataOutputStream out = new DataOutputStream(outToClient);
// From client
InputStream inFromClient = server.getInputStream();
DataInputStream in = new DataInputStream(inFromClient);
// Print info when connected
System.out.println("Just connected to " + server.getRemoteSocketAddress());
// Print message from client
System.out.println("Client says: " + in.readUTF());
// Print message to client
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress());
// Tell client they may begin chatting
out.writeUTF("You may now begin chatting! Type endchat to end the chat!");
// Start reading user input
Scanner chat = new Scanner(System.in);
String lineFrom;
String lineTo;
// Keep the program open as long as the user doesn't type endchat
while (!chat.nextLine().equals("endchat"))
{
// Read from client
lineFrom = String.valueOf(in.readUTF());
System.out.println(lineFrom);
// Send to client
lineTo = chat.nextLine();
out.writeUTF(lineTo + "\n");
}
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
}catch(IOException e)
{
e.printStackTrace();
}
}
public static void main(String [] args)
{
// Get port number and username from command line
int port = Integer.parseInt(args[0]);
String username = args[1];
try
{
// Create and start new Server
Thread t = new Server(port, username);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
EDIT: I added the newline character to my Server class when a message is sent. I'm now receiving the message in my Client class but the message I'm getting is in weird characters.
First separate out your read and write into distinct methods
i.e.
private String read(Server server){
// From client
InputStream inFromClient = server.getInputStream();
DataInputStream in = new DataInputStream(inFromClient);
.....
return message
}
private void write(Server server, String message){
OutputStream outToClient = server.getOutputStream();
DataOutputStream out = new DataOutputStream(outToClient);
......
}
Now use you main/run method to switch between read/write.
If the client writes, the it should wait for a read response and same with the server.
and you can do this while "endChat" is not true.
This is simplistic but it should get you going.
You can use something like this to send and receive messages at the same time.
new Thread(){
public void run(){
try{
while (!chat.nextLine().equals("endChat")){
System.out.println(in.readUTF());
}
}catch(Exception error){error.printStackTrace();}
}
}.start();
new Thread(){
public void run(){
try{
while (!chat.nextLine().equals("endChat")){
out.writeUTF(chat.nextLine());
}
}catch(Exception error){error.printStackTrace();}
}
}.start();