I am connecting to a server written in JAVA using TCP/IP. My application sends json arrays to this server and in some cases also expects some results, json arrays. The problem is that i can easily send json via tcp but when reading it the script freezes waiting forever until it timeouts.
Here is my code.
$sock = socket_create(AF_INET, SOCK_STREAM, 0) //Creating a TCP socket
or die("error: could not create socket\n");
$succ = socket_connect($sock, Application_Model_Config::serverHost, Application_Model_Config::serverPort) //Connecting to to server using that socket
or die("error: could not connect to host\n");
socket_write($sock, $send.'\n', strlen($send)+1);
$response = '';
while ($resp = socket_read($sock, 1024)) {
if (!$resp)
break;
$response .= $resp;
if (strpos($resp, "\n") !== false)
break;
}
echo "Server said: {$response}";
}
$send is a an array encoded as json_encode($array).
Sending is ok but when needed to receive i don't get anything.
I wouldn't mind handling this using jquery (sending and getting json objects from the server) if that would be possible. I am not aware of any implementation that achieves something like this but i'm opened to suggestions...actually would prefer it instead of php.
In the mode you're using socket_read, it has the same semantics as recv:
If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2) ), in which case the value -1 is returned and the external variable errno set to EAGAIN. The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.
Therefore, if the script is "waiting forever until it timeouts" that's because there's no data to read. You can confirm this with a packet sniffer.
Related
I want to transmit an integer number throught a socket.
I have a python script that open a socket and wait for requests, in the other side there is a Java servlet that send a request at this socket to obtain a value.
All the communication works well the problem is that the value obtained from java cause a EOFexception. I've tried some convertion and formats in the python script (I'm not expert of this language) but nothing works.
Instead, if I use in python a echo socket, picking all that socket receive and send back to java, all working fine.
But I need to send a simple value.
The following is the portion of code that I use, I've tried with float, this is with a String value:
[Python socket related istructions]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(server_address)
sock.listen(1)
connection = sock.accept()
[Python echo socket working]
data = connection.recv(16)
if data:
connection.sendall(data)
instead I want to do:
[Python return a example value]
connection.sendall('55')
That working if I send request from a client like Hercules but cause a EOFexception in Java
[Java Servlet - send request]
socket = new Socket(address, port);
dataInputStream = new DataInputStream(socket.getInputStream());
String content = dataInputStream.readUTF(); //EOFexception
Destination.value = content;
Solved the problem by using InputStream instead of DataInputStream, write the python socket to send string as byte and changed the java receiver to read byte stream and convert in to string (good format for my purpose).
Okay, so I have an apache server that has text/data that I want to sendoff to a Java client. The issue is that the data will change often, and I don't want the client to constantly do a read on the server, because obviously I don't want a constant ping. I know that I can make a client socket but that requires my users to port forward to access the server, which isn't going to work for my users.
What I've found online is UDP punching may work or NAT Transfer, but I cant find any examples for how to do it in Java.
If you have any questions please feel free to comment :)
You could Recieve Server-Sent Event notifications, in which the server send the data, using PHP and JS as an example:
var source = new EventSource("demo_sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
PHP:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>
Hi let me get straight to the problem. I have a big JSON packet that the server sends to this client once the client is authenticated
But the packet comes back in a weird way like it's split or something example:
The JSON should be:
Received: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,"ItemSlots":30}
When it comes through:
Received: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,
Received: "ItemSlots":30}
Why does it split the packet or something when it comes to the client and how can I fix this anyway?
Java Receive Code:
private class ClientThread extends Thread {
public void run() {
try {
while (selector.select() > 0) {
for (SelectionKey sk : selector.selectedKeys()) {
selector.selectedKeys().remove(sk);
if (sk.isReadable()) {
SocketChannel sc = (SocketChannel)sk.channel();
ByteBuffer buff = ByteBuffer.allocate(1024);
String content = "";
while (sc.read(buff) > 0) {
sc.read(buff);
buff.flip();
content += charset.decode(buff);
buff.clear();
}
System.out.println("Recieved: " + content);
sk.interestOps(SelectionKey.OP_READ);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks have a wonderful day.
Hi lemme get straight to the problem so i got a big JSON packet that the server sends to this client once the client is authenticated
You mean you have a big JSON message. Packets are things that network protocols used to exchange information.
But the packet comes back in a weird way like its split or something example:
Unless you're looking at the wire, you aren't looking at packets. You're looking at the bytes you got from your end of the TCP connection.
The JSON should be:
Recieved: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,"ItemSlots":30}
When it comes through:
Recieved: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,
Recieved: "ItemSlots":30}
Excellent. You got the same bytes. Now make a JSON parser that figures out where the message ends and parses it.
Why does it split the packet or something when it comes to the client
It splits the message into packets because that's how TCP gets the message to the other side. TCP is not a message protocol and it doesn't know or care what the application considers to be a message -- that's the application's job.
and how i can i fix this anyway?
Write a JSON parser to figure out where the messages end. You haven't implemented any code to receive JSON over TCP yet, so that won't work until you do.
TL;DR: If you want an application-level message protocol, you need to implement one. TCP is not one.
TCP protocol does not maintain message boundaries. It is not guaranteed that what the server sends is received as-is by the client and vice-versa.
If the server sends 1000 bytes data, the client application can receive the same across multiple recv or single recv. TCP does not guarantee any behaviour. "Split" can happen, it is upto the application to handle the data coming in multiple chunks, coalesce it to one unit of application data for further processing. One can see this particularly with large data sizes.
It looks like you've got a non-blocking socket channel, meaning that the while (sc.read(buff) > 0) { loop is terminating due to sc.read(buff) returning 0 since only a portion of the data sent has, at this point, been received.
Why does it split the packet or something when it comes to the client
Most likely the data is being split into two or more packets.
and how i can i fix this anyway?
Keep filling your buffer until the socket is closed by the server (read should return -1 rather than 0 in that case). You need to maintain a separate buffer per channel. If the server doesn't close its end after sending the data, you'll need to delineate in some other way; you could prefix the JSON blob with a size header, for instance.
I am using the below code to send data to a tcp server. I am assuming that I need to use socket.shutdownOutput() to properly indicate that the client is done sending the request. Is my assumption correct? If not please let me know the purpose of shutdownOutput(). Also appreciate any further optimizations I can make.
Client
def address = new InetSocketAddress(tcpIpAddress, tcpPort as Integer)
clientSocket = new Socket()
clientSocket.connect(address, FIVE_SECONDS)
clientSocket.setSoTimeout(FIVE_SECONDS)
// default to 4K when writing to the server
BufferedOutputStream outputStream = new BufferedOutputStream(clientSocket.getOutputStream(), 4096)
//encode the data
final byte[] bytes = reqFFF.getBytes("8859_1")
outputStream.write(bytes,0,bytes.length)
outputStream.flush()
clientSocket.shutdownOutput()
Server
ServerSocket welcomeSocket = new ServerSocket(6789)
while(true)
{
println "ready to accept connections"
Socket connectionSocket = welcomeSocket.accept()
println "accepted client req"
BufferedInputStream inFromClient = new BufferedInputStream(connectionSocket.getInputStream())
BufferedOutputStream outToClient = new BufferedOutputStream(connectionSocket.getOutputStream())
ByteArrayOutputStream bos=new ByteArrayOutputStream()
println "reading data byte by byte"
byte b=inFromClient.read()
while(b!=-1)
{
bos.write(b)
b=inFromClient.read()
}
String s=bos.toString()
println("Received request: [" + s +"]")
def resp = "InvalidInput"
if(s=="hit") { resp = "some data" }
println "Sending resp: ["+resp+"]"
outToClient.write(resp.getBytes());
outToClient.flush()
}
I am using the below code to send data to a tcp server. I am assuming
that I need to use socket.shutdownOutput() to properly indicate that
the client is done sending the request. Is my assumption correct?
YES Your assumption is correct. And this output ShutDown is known as half close . Using half close the TCP provides the ability for one end of the connection to terminate its output, while still receiving data from the other end. Let me walk you through the effects of socket.shutdownOutput() method :
Locally, the local socket and its input stream behave normally for reading
purposes, but for writing purposes the socket and its output stream behave
as though the socket had been closed by this end: subsequent writes to the
socket will throw an IOException
TCP’s normal connection-termination sequence (a - FIN acknowledged by
an ACK) is queued to be sent after any pending data has been sent and acknowledged.
Remotely, the remote socket behaves normally for writing purposes, but for
reading purposes the socket behaves as though it had been closed by this
end: further reads from the socket return an EOF condition, i.e. a read count
of -1 or an EOFException , depending on the method being called.
When the local socket is finally closed, the connection-termination sequence
has already been sent, and is not repeated; if the other end has already
done a half-close as well, all protocol exchanges on the socket are now
complete.
Hence we see that When the EOF is received, that end is assured that the other end has done the output shutdown. And this scenario is perfectly achieved by socket.shutDownOutput() on the other side.
Source: Fundamental Networking in Java, Esmond Pitt
Socket.shutdownOutput() means that the client is finished sending any data through the TCP connection. It will send the remaining data followed by a termination sequence which will completely close its OUTGOING connection. It is not possible to send any further data, which will also indicate to your program that the request is completely finished. So its recommended if you are sure you don't have to send any more data.
But it's not needed to indicate that the request is finished (you don't have to open/close the output all the time if you have multiple requests), there are other ways.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A PHP Socket Server with Flash Clients
I am building an app in my server with the help of a flash developer, and he asked me to build a socket server to communicate with the database. He recommended me JAVA but I am not very good at JAVA and I was wondering if it was possible to build a Socket Server in PHP.
I should allow connections to multiple TCP client connections. I know in JAVA this is done thought threading, but I am not sure if this can also be achieved with PHP.
Could someone please show me the basic skeleton of a PHP Socket Server with these characteristics?
The connection has to be TCp (persistent) from the beginning of the connection to the app, until the end.
You have to run your socket server as a service from the command line.
This is a part of what I have used before. It closes the socket after a read but can easy be modified to keep a array of connections.
You would have to build some kind of watchdog to see if a connection is still alive.
You need a identifying mechanism to identify different connections.
The code:
set_time_limit( 0 );
// Set the ip and port we will listen on
$address = '127.0.0.1';
$port = 6789;
// Create a TCP Stream socket
$sock = socket_create( AF_INET, SOCK_STREAM, 0 ); // 0 for SQL_TCP
// Bind the socket to an address/port
socket_bind( $sock, 0, $port ) or die( 'Could not bind to address' ); //0 for localhost
// Start listening for connections
socket_listen( $sock );
//loop and listen
while (true) {
/* Accept incoming requests and handle them as child processes */
$client = socket_accept( $sock );
// Read the input from the client – 1024000 bytes
$input = socket_read( $client, 1024000 );
// from here you need to do your database stuff
// and handle the response
// Display output back to client
socket_write( $client, $response );
socket_close( $client );
}
// Close the master sockets
socket_close( $sock );
There is a WebSocket Server and Client library for PHP At Google code . It supports flash clients . Not sure whether it solves your problem .
If you want a basic tutorial here is the link to learn
How to create a socket server in php
EDIT :- after looking at your comment ( running a socket server continuously as a service )
Here is the link which describes the way of creating a socket server and running as a process
Create a socket server in php and run as a service
Rather than building a "socket server", you should really build a set of web APIs (SOAP, REST/JSON, whatever) that provides limited and well-defined access to the DB. Then have the Flash app use that.
Your flash app sends JSON over a RESTful interface, or SOAP/XML requests. The server receives them, interacts appropriately with the database, and returns any required results again as XML or JSON.