I am programming a server socket for java that takes data from a client socket, processes them and sends a response back.
At the current state I am able to send data and process it, but unfortunately I wasn't able to figure out how to send the processed data from the server socket to the client socket. I already tried using the example provided from php.net, but that just somehow just blocks the sending of my data. I also tried to only read or write and that worked like a charm.
My server socket (java) looks as follows:
public class TcpListener {
public static String clientSentence;
private static ServerSocket serverSocket;
public static void main(String argv[]) throws Exception{
serverSocket = new ServerSocket(49654);
Socket connectionSocket = serverSocket.accept();
while(true)
{
//read
int reportId = read(connectionSocket);
//write
write(connectionSocket, reportId);
}
//connectionSocket.close();
}
public static int read(Socket connectionSocket) throws IOException{
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println(clientSentence);
Report r = new Report(clientSentence);
int reportId = r.main();
inFromClient.close();
return reportId;
}
public static void write(Socket connectionSocket, int id) throws IOException{
PrintWriter outToClient = new PrintWriter(connectionSocket.getOutputStream(), true);
System.out.println(id);
outToClient.println(id);
outToClient.flush();
outToClient.close();
}
}
and my client socket (php):
set_time_limit(0);
ob_implicit_flush();
$host = "localhost";
$port = 49654;
if (($socket = socket_create(AF_INET, SOCK_STREAM, 0)) === false) {
echo "\nsocket_create() failed: reason: " . socket_strerror(socket_last_error());
} else {
echo "\nAttempting to connect to '$host' on port '$port'...\n";
if (($result = socket_connect($socket, $host, $port)) === false) {
echo "socket_connect() failed. Reason: ($result) " . socket_strerror(socket_last_error($socket));
} else {
socket_set_nonblock($socket);
echo "Sending data...\n";
$sresult = socket_send($socket, $message."\r\n", strlen($message), MSG_DONTROUTE);
if ($sresult === false) {
$errorcode = socket_last_error($socket);
$errormsg = socket_strerror($errorcode);
die("error sending data. " . $errormsg. "($errorcode)");
}
echo "OK\n";
echo "Reading response:\n\n";
while(socket_recv ( $socket , $buf , 2045 , MSG_WAITALL ) === FALSE){
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("Could not receive data: [$errorcode] $errormsg \n");
}
echo $buf;
}
echo "close";
socket_close($socket);
}
The following error message is being displayed:
Warning: socket_recv(): unable to read from socket [10045]: The attempted operation is not supported for the type of object
referenced. <b>D:\xampp\htdocs\api\select\getApps.php</b> on line <b>75</b><br />
Could not receive data: [10045] The attempted operation is not supported for the type of object referenced.
Where line 75 is the while loop.
I would appreciate any help on how to fix my problem.
Related
I have set up an pi zero running a simple python server script on my local network to respond to certain commands. I am trying to send those commands from an android java app. But when I try to read the reply from the command I have sent it seems like it skipes the line. Because "D/Sending data: Data has been send" is the last thing printed to the log.
This is the nested runnable class I am using to sent a command and then print the reply from the server:
private class SendData implements Runnable
{
private byte[] dataToSend;
private Socket socket;
private OutputStream outputStream;
private BufferedReader bufferedReader;
public SendData(Socket socket, byte[] dataToSend)
{
this.socket = socket;
this.dataToSend = dataToSend;
}
#Override
public void run()
{
try
{
outputStream = socket.getOutputStream();
outputStream.write(dataToSend);
Log.d("Sending data", "Data has been send");
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.d("Received", bufferedReader.readLine());
}
catch (IOException e)
{
Log.e("IOException Sending data", e.getMessage());
}
}
}
But when I try to read from the bufferedreader the applications just quits. While the server did sent a reply.
The thread gets started from from this method where "data" is a string.
if (socket != null)
{
Thread sendThread = new Thread(new SendData(socket, data.getBytes()));
Log.d("SocketClient send", "Starting send thread");
sendThread.start();
try
{
sendThread.join();
}
catch (InterruptedException e)
{
Log.d("SocketClient constructor", "Could not join");
}
}
else
{
Log.d("SocketClient send", "Socket is null");
}
Python script running on the pi:
import socket
import sys
from datetime import datetime
host = "192.168.4.1"
port = 12345
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(1)
def data_client(conn, ipStr):
while True:
data = conn.recv(2048)
reply = handle_command(data)
print "Command: %s" % data
if not data or data == "con_close":
print "Connection %s closed" % ipStr
break
conn.send(reply)
print "Send: %s" % reply
conn.close()
def handle_command(cmd):
if (cmd == "con_close"):
return cmd
elif (cmd == "get_time"):
return str(datetime.now())
else:
return "err_invalid_command"
while True:
print "listening:"
conn, addr = sock.accept()
print "Got connection from %s" % addr[0]
data_client(conn, addr[0])
If the receiver tries to read a line then the sender should have send one.
The receiver tries to read a line with readLine() but readLine() never returns as it waits for a newline char that has not been sent.
I am trying to establish communication between a SocketServer (Server) in Java and a Socket (Client) in php.
The client is able to connect to host, the client is able to send a message and the server reads the message successfully. But the problem arises when the SocketServer writes to the Client, the client does not receive the message from the server.
I have read the other questions on the same scenario (java-php socket communication) but i just can't seem to find what is causing the problem.
If i use a Java Socket as a client the communication works perfectly both ways.
The Server :
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
protected ServerSocket socket;
protected final int port = 9005;
protected Socket connection;
protected String command = new String();
protected String responseString = new String();
public void init(){
System.out.println( "Launching Server: " );
try{
socket = new ServerSocket(port);
while(true)
{
// open socket
connection = socket.accept();
System.out.println( "Client Connected " );
// get input reader
InputStreamReader inputStream = new InputStreamReader(connection.getInputStream());
BufferedReader input = new BufferedReader(inputStream);
// get input
command = input.readLine();
// process input
System.out.println("Command: " + command);
responseString = command + " MC2 It Works!";
// get output handler
PrintStream response = new PrintStream(connection.getOutputStream());
// send response
response.println(responseString);
}
}
catch (IOException e){
e.printStackTrace();
}
}
}
The Client :
class Client {
private $address;
private $port;
public function __construct($address, $port){
$this->address = $address;
$this->port = $port;
$this->init();
}
private function init(){
//create socket
if(! $socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'))){
$this->showError("socket create");
};
//establish connection
socket_connect($socket, $this->address, $this->port);
//write to server
$message = "I am a client";
socket_write($socket, $message, strlen($message)); //Send data
echo "Listening to Server\n";
//read from server
if(!$reponse = socket_read($socket, 2048, PHP_NORMAL_READ)){
$this->showError("socket read");
}
//print response
echo "Response from server------------------\n";
echo $reponse;
socket_close($socket);
}
private function showError($message){
echo ("Error: ".$message);
exit(666);
}
}
$address="localhost";$port=9005;
echo "Testing Client Server\n";
$client = new Client($address, $port);
Could someone please guide me to what could be the problem here ?
In server side, the code expects a line(terminated with linefeed), in php You send
socket_write($socket, $message, strlen($message));
Please check the data you send accordingly making sure that you send the linefeed character.
I am trying to communicate from php to java using sockets. I have the following java code:
private static ServerSocket socket;
private static Socket connection;
private static String command = new String();
private static String responseStr = new String();
private static int port = 2500;
public static void main(String args[]) {
System.out.println("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();
}
} catch (IOException e) {
System.out.println("Fail!: " + e.toString());
}
}
I have the following PHP code:
<?php
$socket = stream_socket_server("tcp://192.168.0.10:2500", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}
fclose($socket);
}
I start the java app, which starts fine, When I run the php, I get the following error:
An attempt was made to access a socket in a way forbidden by its access permissions. (0)
I have searched Google and have tried all the solutions I could find although nothing has worked. I have restarted both machines and disabled the firewall, neither worked.
I am not sure where to go from here.
[update from comment:]
192.168.0.10 is the machine with the java app and web server on it. I am connecting from another machine 192.168.0.7
You can only can create a socket on the machine were the code is running on.
So if the PHP code is run on 192.168.0.7, then do:
$socket = stream_socket_server("tcp://192.168.0.7:2500", $errno, $errstr);
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();
I am trying to create a simple HTTP web server in Java. I'm just taking this in baby steps so it's super simplistic. I'm trying to make it so I can read simple input from the Client and output anything from the Server when they are both connected.
After searching around on tutorials on websites, this is what I've done so far:
public class Server
{
public static void main(String[] args) throws Exception
{
boolean listening = true;
ServerSocket server = null;
int port = 2222;
try
{
System.out.println("Server binding to port " + port);
server = new ServerSocket(port);
}
catch(Exception e)
{
System.out.println("Error: " + e);
System.exit(1);
}
System.out.println("Server successfully binded to port " + port);
while(listening)
{
System.out.println("Attempting to connect to client");
Socket client = server.accept();
System.out.println("Successfully connected to client");
new ServerThread(client).start() ;
}
server.close();
}
}
public class ServerThread extends Thread
{
private Socket socket = null ;
public ServerThread(Socket s)
{
this.socket = s ;
}
public void run()
{
InputStream in = socket.getInputStream() ;
OutputStream out = socket.getOutputStream() ;
byte [] message, reply;
while((in.read(message))
{
out.write(reply) ;
}
in.close() ;
out.close() ;
socket.close() ;
}
}
It binds and then hangs after attempting to connect to the client. This is because I'm not sure what you do in the while loop in the ServerThread and what you do with the message and reply variables >_< It's been a long time since I've done Java so take it easy on me!
I have only use this kind of server as a "curiosity", to learn new stuff nothing more because you are reinventing the wheel, security reasons etc... I only had to use it once because I had to communicate a server with a JSON code and no server could be installed.
This code needs more work such us creating a new thread for each request, a better RCF HTTP implementation but it works with your ordinary browser.
I hope this helps.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MiniPbxManServer extends Thread {
private final int PORT = 2222;
public static void main(String[] args) {
MiniPbxManServer gtp = new MiniPbxManServer();
gtp.start();
}
public void run() {
try {
ServerSocket server = new ServerSocket(PORT);
System.out.println("MiniServer active "+PORT);
boolean shudown = true;
while (shudown) {
Socket socket = server.accept();
InputStream is = socket.getInputStream();
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
line = in.readLine();
String auxLine = line;
line = "";
// looks for post data
int postDataI = -1;
while ((line = in.readLine()) != null && (line.length() != 0)) {
System.out.println(line);
if (line.indexOf("Content-Length:") > -1) {
postDataI = new Integer(line
.substring(
line.indexOf("Content-Length:") + 16,
line.length())).intValue();
}
}
String postData = "";
for (int i = 0; i < postDataI; i++) {
int intParser = in.read();
postData += (char) intParser;
}
out.println("HTTP/1.0 200 OK");
out.println("Content-Type: text/html; charset=utf-8");
out.println("Server: MINISERVER");
// this blank line signals the end of the headers
out.println("");
// Send the HTML page
out.println("<H1>Welcome to the Mini PbxMan server</H1>");
out.println("<H2>GET->"+auxLine+ "</H2>");
out.println("<H2>Post->"+postData+ "</H2>");
out.println("<form name=\"input\" action=\"imback\" method=\"post\">");
out.println("Username: <input type=\"text\" name=\"user\"><input type=\"submit\" value=\"Submit\"></form>");
//if your get parameter contains shutdown it will shutdown
if(auxLine.indexOf("?shutdown")>-1){
shudown = false;
}
out.close();
socket.close();
}
server.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
url: localhost:2222/whatever
I think you're going the right way at a high level. The difference between what you've got and production systems is that they do their polling for input on a socket is done in a different thread so as not to halt the system while waiting for input.
In fact, one of the configuration parameters for a web server is how many clients (threads) to have up and running.
You should always flush data from the server's output stream. The client response may depend on this:
out.flush();
To check for the end of stream, you could use:
int result = 0;
while ((result = in.read(message)) != -1) {
...
Also your reply message does not appear to be initialized, you probably want to resend the client data initially:
reply = message;
The jdk has a simplistic http server included to build embedded http servers. Take a look at this link.