Using sockets with PHP and Java - java

I attempted to create a PHP script which determines if the server (the computer which hosts the java program listed below) is running or not, If it is, the php funciton should return true, if not it returns false.
Here is the server:
package darestium.minecraft.server;
import java.io.BufferedReader;
import java.net.*;
import java.io.*;
public class Server {
private static ServerSocket socket;
private static Socket connection;
private static String command = new String();
private static String responseStr = new String();;
private static int port = 4343;
public static void main(String args[]) {
System.out.println("Signal Server is running.");
try {
socket = new ServerSocket(port);
while (true) {
connection = socket.accept();
InputStreamReader inputStream = new InputStreamReader(connection.getInputStream());
DataOutputStream response = new DataOutputStream(connection.getOutputStream());
BufferedReader input = new BufferedReader(inputStream);
command = input.readLine();
response.writeBytes(responseStr);
response.flush();
//response.close();
System.out.println("Running");
}
} catch (IOException e) {
System.out.println("Fail!: " + e.toString());
}
System.out.println("Closing...");
}
}
And here is the client:
<?
function isRunning() {
$address = 'darestium.dyndns-free.com';
$port = 4343;
$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
$message = 'loolololol';
try {
socket_connect($socket, $address, $port);
$status = socket_sendto($socket, $message, strlen($message), MSG_EOF, $address, $port);
if ($status != false) {
return true;
}
return false;
} catch (Exception $e) {
return false;
}
}
?>
The following are the error messages that show up on the php page that echos out the result of the function like so:
include('server.php');
echo isRunning();
Then the error messages:
Warning: socket_connect() [function.socket-connect]: unable to connect [0]: No connection could be made because the target machine actively refused it. in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 9
Notice: Use of undefined constant MSG_EOF - assumed 'MSG_EOF' in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 11
Warning: socket_sendto() expects parameter 4 to be long, string given in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 11
I was wondering how I could fix this issue. Also, I would like to be able to send messages to the server, any ideas how I could do this? I am basing this off Simple Java TCP Server and PHP Client Problems
Note: that I am very new to Sockets, and Server/Client communication.
Edit:
#VideanuAdrian OK, just port forwarded the port 4343 and it no longer shows up with the first error, but the function always seems to return false, and the last two errors still show.

You should not close the DataOutputStream object in your server.
Just comment the line response.close(); in your server and the program should work.

When running a Client/Server you need to know if the user that runs the app has access to the port. Ports to 1024 are reserved by the system know apps/services. That´s point 1.
Point 2: One of the best ways is to run the server inside a connection-thread approach. Running in this way, when a new client request arrives, the server can delegate the request handle to the connection thread.
Point 3: The message is related to the protocol. If you are using a built protocol like HTTP or FTP, you must use the protocol rules. If not, you could built your own rules for the message request/response.
I recomend you to read the Java Networking Tutorial before continue. Run all Java examples. Later, you could mix with PHP. The more information about sockets and protocols you have, the better your programm will be.
http://docs.oracle.com/javase/tutorial/networking/
Hope this can help you.

Related

localhost works in Edge but not in Chrome

I'm doing an on-line Java course and created a very simple server. Using Edge as client it works but not with Chrome. I've tried turning off firewall and some of the things suggested here (WAMP server localhost wont work with Chrome) and elsewhere, but they all seem to be overly complicated changes to Windows files. Surely there's a config setting somewhere?!
In Edge it's fine, in Chrome it returns this whether I use localhost:999 or 127.0.0.1:999. I've tried other ports too.
This page isn’t working
127.0.0.1 sent an invalid response.
ERR_INVALID_HTTP_RESPONSE
Here is my code in case needed.
public static void main(String[] args) {
try (
ServerSocket aServer = new ServerSocket(999);
Socket cn = aServer.accept();
BufferedReader bis = new BufferedReader(new InputStreamReader(cn.getInputStream()));
BufferedOutputStream bos = new BufferedOutputStream(cn.getOutputStream());)
{
String line = bis.readLine();
while(line != null && !line.equals(""))
{
System.out.println(line);
line = bis.readLine();
}
bos.write("Hello from java TCP Server!".getBytes());
} catch (IOException ex) {
System.out.println("Error in connnection: " + ex.getMessage());
}
}
Any help appreciated.
Web browsers require that the server speaks HTTP protocol. A proper server response would be:
BufferedOutputStream bos = new BufferedOutputStream(System.out);
byte[] message="Hello from java TCP Server!".getBytes();
bos.write("HTTP/1.1 200 OK\r\n".getBytes());
bos.write("Content-Type: text/plain\r\n".getBytes());
bos.write(("Content-Length: "+message.length+"\r\n").getBytes());
bos.write("\r\n".getBytes()); // empty line between HTTP header and HTTP content
bos.write(message);
You may test your program with another tool that speaks plain TCP sockets. Ich recommend "Netcat" (command: nc). Download for Windows: http://stefanfrings.de/avr_tools/netcat-win32-1.12.zip

Netty: Keep Server Socket Open After ctx.flush()

I have two servers "A" (built by my friends) and "B" (built by me, using Netty 4.1). this server "A" and "B" would return some response when the client sends a command. I tried to that server using simple JAVA Client Socket. below is the java client code:
public class SocketClient
{
public void run()
{
try {
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("request.txt").getFile());
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println("Connecting to server:8888");
Socket socket = new Socket("myserver.com", 8888);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write(content.getBytes());
out.flush();
while(true) {
int response = in.read();
System.out.println(response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
When connect the client to server A (non-netty), the read() method give me the output like this:
48
48
57
56
48
50
49
48
but, when i try to connect to Server "B" (which is using netty), the output is like this:
48
48
57
56
48
50
49
48
-1
-1
-1
-1
why does this happen? by the way in server B I'm using ctx.write() and ctx.flush() and how to make server B get the same behavior with server A (not closing the connection, so it won't return -1)
edit: Additional Information
Actually in server "B" i'm using ChannelInboundHandlerAdapter and ChannelOutboundHandlerAdapter. After doing some experimentation the problem is on ChannelOutboundHandlerAdapter. When i send response using ctx.writeAndFlush() from InboundAdapter, the socket is not closed. But when the response is passed into OutboundAdapter and then i send the response using ctx.writeAndFlush() inside OutboundAdapter write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) method. The socket is closed
here is the sample of my OutboundAdapter:
public class OutboundHandler extends ChannelOutboundHandlerAdapter {
private static final Logger logger = LogManager.getLogger(OutboundHandler.class);
//Sending or forwarding message to channel which is already configured
//condition is depends on which model instance
//packaging is worked on its packager class
#Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception
{
String response = "Response form OutboundHandler";
ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
} }
thanks
On Netty Server Implementation, maybe you have to handle reading/writing via ChannelHandlerContext more properly for example, instead of using ctx.write() ctx.channel().writeandflush() should be more proper way, also in closing usage of ctx.channel().close() or ctx.channel().close().sync() could make differences...
You aren't checking for end of stream, so you are echoing it endlessly. read() returns a value. Check it. It returns -1 at end of stream. That's the end. Finis. Finito. Stop there. Don't print it. Don't keep reading. Do not pass GO. Do not collect $200.
After debugging all-day, i found the root cause of the problem. I accidentally put ctx.close() somewhere in my InboundAdapter, so when i pass the message into OutboundAdapter and the flush the message to client it will close the connection
try {
//some code
}
} catch (Exception ex) {
logger.error(ex);
ErrorData error = new ErrorData();
error.setCode("99");
error.setMessage("General System Error");
//pass the message to OutboundAdapter
ctx.writeAndFlush(error);
} finally {
ctx.close();
}
So, i just need to remove the ctx.close() and the server stopped from closing the socket connection

Multiple threaded socket server in Java

I recently tried creating a socket server which can connect to multiple clients... I was too lazy to write a separate program for the client so I'm just using telnet.
The first time I connect(using telnet), it works fine... but the second telnet connection just hangs and the cmd screen goes blank...
Even the first connection gets hanged after sending a string.
Any help is appreciated
Here's the code:
Chatserver.java
I would really appreciate I if someone would correct the mistakes in the code and post it
You could have a look at it if you want but it might be easier if you just clicked the hyperlink and viewed the image:
package chatserver;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
class Chat extends Thread {
#Override
public void run() {
Chat server = new Chat();
try {
server.SERVER();
} catch (Exception ex) {
Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void SERVER() throws Exception {
ServerSocket SRVSOCK = new ServerSocket(8068);
Socket SOCK = SRVSOCK.accept();
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("What is your name: ");
String name = BR.readLine();
String Message = BR.readLine();
PS.println(name + " : " + Message);
}
}
public class ChatServer {
public static void main(String[] args) {
Chat c1 = new Chat();
Chat c2 = new Chat();
while (true) {
c1.start();
c2.start();
}
}
}
Guys,
Today I typed up the same code in python as I am much more familiar with it than I am with Java
I have succeeded in connecting to multiple clients but am unable to see outputs from chat() yet...
I would like to know what mistake I made in this code below and would be very grateful if someone helps me transcribe it to Java:
#!/usr/bin/env python3
import socket
import threading
import time
clients = []
addr = []
HOST = '127.0.0.1'
PORT = 8068
client_no = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print('Socket bind complete')
def connect(clnt_no):
while True:
s.listen(1)
print('searching for clients')
clnt, adr = s.accept()
clients.append(clnt)
addr.append(adr)
print('connected to: ',addr[clnt_no])
# print(len(clients))
clnt_no += 1
client_no = clnt_no
def chat():
while True:
for x in range(0, client_no):
data = clients[x] = recv(1204)
if data:
for y in range(0, client_no):
clients[y].send('from client ', x, ' ', data)
else:
print('no data recieved from any client')
def Main():
conn = threading.Thread(target=connect, args=[0])
cht = threading.Thread(target=chat)
# while True:
conn.start()
cht.start()
if(__name__ == '__main__'):
Main()
Thanks in advance
Two problems:
First, every instance of Chat is listening on port 8068. You can only have one ServerSocket listening on a particular port, though it is free to accept() multiple connections. If you paid attention to the exceptions you’re getting instead of ignoring them, you would see an exception informing you of this.
Second, since the start() method of Thread returns immediately rather than waiting for the thread to finish, your while loop is creating hundreds, if not thousands, of threads. The only reason your system isn’t overwhelmed by them is because, as I mentioned above, all but the very first instance are immediately failing to bind their ServerSockets, so they return fairly quickly.
In summary, you need to create one server, with one ServerSocket. You will need to call accept() inside a loop, but you must not create more than one ServerSocket.

Sending strings over socket

So I'm trying to communicate via client/server using sockets between a raspberry pi and a laptop. I've been able to send basic strings over using a simple python script on my pi to get the basic idea of how it worked. Now I got a little more advanced and started using OpenCV along with a usb camera to make a little security system that detects motion in the frame of the camera. I have the python script with the security system connect with the server and it is supposed to print out "Occupied" or "Unoccupied" in the console on my laptop in real time (eventually supposed to open a pop-up menu alerting that motion is detected) but it only prints out a long huge string of either "Occupied" or "Unoccupied" once I close the connection with my Pi. Why isn't it printing out in real time? Here is the java code on my laptop, unforunately my Pi is in school at the moment and I can't access the python code but I will post it tomorrow.
public class PyComms {
public static void main(String[] args) {
try{
ServerSocket server = new ServerSocket(4444);
System.out.println("Waiting for client on port 4444");
while(true){
Socket connected = server.accept();
System.out.println("CONNECTED WITH CLIENT");
BufferedReader inFromPi = new BufferedReader(new InputStreamReader(connected.getInputStream()));
while(true){
String fromclient = inFromPi.readLine();
if(fromclient.equalsIgnoreCase("Occupied")){
System.out.println("Client responded with "+fromclient + "\n");
}
else{
System.out.println("Client responded with "+fromclient + "\n");
connected.close();
}
}
}
}
catch(Exception e){
System.out.println(e);
}
}
}
The answer was exactly what #jtahlborn said. All I had to do was include a new line after each message was sent in the python code. I achieved this by doing something similar to client_socket.send(text+'\n')

Client-Server example does not work

I studied the Client-Server chapter of a Java book and I copied the code examples for a easy Client-Server interaction.
The server:
package knowledge;
import java.io.*;
import java.net.*;
public class DateTimeServer {
public static void main(String[] args) {
try {
int port = Integer.parseInt(args[0]);
ServerSocket server = new ServerSocket(port);
System.out.println("DateTimeServer laeuft");
Socket s = server.accept();
new DateTimeProtokoll(s).transact();
} catch (ArrayIndexOutOfBoundsException ae) {
System.out.println("Aufruf: java DateTimeServer <Port-Nr>");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Protocol:
package knowledge;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
public class DateTimeProtokoll {
static SimpleDateFormat time = new SimpleDateFormat(
"´Es ist gerade´H´.´mm´ Uhr.´");
static SimpleDateFormat date = new SimpleDateFormat(
"´Heute ist´EEEE´, der ´dd.MM.yy´");
Socket s;
BufferedReader vomClient;
PrintWriter zumClient;
public DateTimeProtokoll(Socket s) {
try {
this.s = s;
vomClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
zumClient = new PrintWriter(s.getOutputStream(), true);
} catch (IOException e) {
System.out.println("IO-Error");
e.printStackTrace();
}
}
public void transact() {
System.out.println("Protokoll gestartet");
try {
zumClient.println("Geben Sie DATE oder TIME ein");
String wunsch = vomClient.readLine();
Date jetzt = new Date();
if (wunsch.equalsIgnoreCase("date"))
zumClient.print(date.format(jetzt));
else if (wunsch.equalsIgnoreCase("time"))
zumClient.println(time.format(jetzt));
else
zumClient.println(wunsch + "ist als Kommando unzulaessig!");
s.close();
} catch (IOException e) {
System.out.println("IO-Error");
}
System.out.println("Protokoll beendet");
}
}
The Client:
package knowledge;
import java.net.*;
import java.io.*;
public class DateTimeClient {
public static void main(String[] args) {
String hostName="";
int port;
Socket c=null;
try{
hostName=args[0];
port= Integer.parseInt(args[1]);
c=new Socket(hostName,port);
BufferedReader vomServer=new BufferedReader(
new InputStreamReader(c.getInputStream()));
PrintWriter zumServer=new PrintWriter(c.getOutputStream(),true);
BufferedReader vonTastatur=new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Server "+ hostName+":"+port+ "sagt:");
String text=vomServer.readLine();
System.out.println(text);
text=vonTastatur.readLine();
zumServer.println(text);
text=vomServer.readLine();
System.out.println(text);
c.close();
}
catch(ArrayIndexOutOfBoundsException ae){
System.out.println("Aufruf:");
System.out.println("java DateTimeClient <HostName><PortNr>");
}
catch(UnknownHostException ue){
System.out.println("Kein DNS-Eintrag fuer: "+hostName);
}
catch(IOException e){
System.out.println("IO-Error");
}
}
}
Here are some notes of my approach and my beliefs. Please disagree on wrong statements stated below:
1)I believe it is no problem to run Client as well as Server on the same (my) computer.
2)I use Eclipse, so I run Eclipse two times in two different workspaces.
3)My input for server program is (run configuration->arguments): 2222
4)My input for the client program is: 2223 my_ip
(my_ip is for example 127.0.0.1 I choosed to write my_ip instead because I am not sure if it is dangerous to reaveal my ip in public)
4b) also: "2223" "my_ip"
4c) and: {"2223","my_ip"}
5) also 2222 my_ip
(although the figure in my book suggests that the port numbers of client and server should be different, but you never know)
Also I get this very often this error message:
Address already in use sounds like client and server port numbers should be different. But I dont know and thats why I ask. Thank you for your help
(The page did not like my code so I took screenshots :/)
I replaced the images with code. Sorry for the inconvenience.
Restarting first the server with input 2222 and then the client with input 127.0.0.1 2222. After a while the client posts "IO-Error". Its the exception from the clien class (not from protocol class) right? Why is the exception triggered? Is the code working for someone? Thank you
1) Correct. Client and server can be on the same computer, no problem there.
2) Not required, but ok.
3) This will make the server listen on port 2222
4) 127.0.0.1 is just another way of saying "this computer". It is the same as "localhost". Your actual ip is irrelevant to the question anyway, 127.0.0.1 will suffice.
5) Your server is asking on which port to listen (the SOURCE port), your client is asking to which port to connect to (the TARGET port of the client). Of course that should be the SAME port, otherwise the client will try to send a message to port X while the server will listen on port Y.
Imagine the ip as a house address, for example "Mainstreet 12, MyCity". The port would be the appartment number then. Your server occupies appartment 2222, so of course the client needs to try to connect to appartment 2222, otherwise it will not reach any server.
The error is most likely just because you don't actually stop your old server program. Stop it (big red button in eclipse), otherwise it will "occupy" the given port (which will prevent any other program from listing at that port, thus you cannot have two servers running which are both listening on the same port). If we reuse my crude analogy: An appartment cannot contain two servers at the same time, so if one is already in appartment 2222, a second one trying to live there will fail.
I don't know exactly why, but usually server binds host as 127.0.0.1 or localhost or your IP like 192.168.1.100 but if one of that are not listed, than it might be failed to call. See more with netstat.exe on Windows.
The "Address already in use" exception is only because the last Java session still running, could not terminate for some reason, and if you use IDE like Eclipse, it will often happen. :)
Make sure that all java thread is terminated (with task manager in Windows). Note that Eclipse is a Java thread too! You would better run the server in console mode..
In real world, native sockets are rarely used, because there some higher level protocol and technology like HTTP, SOAP, WebService, microService, SOA etc. If native socket is not necessary, for example you communicate with microcontroller, you should use these technologies, because these are more robust and others can easily communicate with your interface.

Categories

Resources