I have an php application, which connects to a java application using sockets. In java application we have timeout set for 10 seconds.
I have a huge amount of data which needs to be processed in the middle of the application. Due to which when i try to use the socket after processing I receive the socket error of connection reset by peer.
Now when I try to shutdown(socket_shutdown) the connection and re open the connection, am receiving an error Transport endpoint is not connected on socket_send,socket_receive. Would appreciate any guidance on this issue.
NOTE : am trying to use singleton method for socket connections.
I am using in my PHP application massively socket connections [10 different PHP Apache threads per second to my own self written C++ Server].
This is the code which I use in PHP and it works:
$sIP = gethostbyname('MyDomain');
# create the socket
$iSocket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
if ($iSocket === FALSE )
{
writeLogFile(sprintf("socket_create() failed: %s",
socket_strerror(socket_last_error())));
exit;
}
# load some default values from the app table
$iTimeOut = 180
$iPort = 11211;
socket_set_option($iSocket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $iTimeOut, "usec" => 0));
$iResult = socket_connect($iSocket, $sIP, $iPort);
if ( $iResult === FALSE )
{
$sError = sprintf("<br>socket_connect(%d) failed with code %d: %s",
$iSocket, $iResult, socket_strerror(socket_last_error($iSocket)));
writeLogFile($sError);
die($sError);
exit;
}
# $sHttpParameter has the value which has to be sent over the socket
socket_write($iSocket, $sHttpParameter, strlen($sHttpParameter));
# for my purpose the answer is just an OK/FAILED
$sAnswer = socket_read($iSocket, 1000);
socket_close($iSocket);
Are you sure the problem is not the JAVA application?
Related
EDIT: For the solution, scroll down to the end of this post!
I have built a Socket IO + node.js chat application which works seamlessly using a web client. I can use the external IPv4 IP address to access the client across different machines on the same network. However, using socket.io-client-java in my Wear OS application is giving me issues. Specifically, an xhr poll error, every time I try to connect to the server.
I have made sure that my server is running, I have enabled android:usesCleartextTraffic="true" in AndroidManifest, and have tried changing a variety of options for my socket. I have tried several stackoverflow solutions regarding this issue, to no avail unfortunately.
Below is my index.js code, which is my server.
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
/**
* Initializes app to be a function handler that can supply to
* an HTTP server: in this case, index.html is served
*/
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
/**
* Initialize a new instance of socket.io by passing
* the server object. Listen on the 'connection' event
* for incoming sockets and log to the console.
*/
io.on('connection', (socket) => {
console.log('a user connected');
console.log(socket.handshake.query);
console.log(socket.handshake.headers);
console.log(socket.handshake.auth.token);
io.emit('chat message','user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
// Let connected users know that a user disconnected
io.emit('chat message','user disconnected');
});
});
/**
* This will emit the event to all connected sockets.
* In this case the event is receiving a chat message.
*/
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
});
/**
* This tells the server to listen on port 3000
*/
server.listen(3000, () => {
console.log('listening on *:3000');
});
I am creating my client socket as such in MainActivity.java:
private Socket mSocket;
{
URI uri = URI.create("http://LOCAL_IP_ADDRESS:3000");
IO.Options options = IO.Options.builder()
.setUpgrade(false)
.build();
mSocket = IO.socket(uri, options);
Log.d("mSocket created: ", "true");
}
The IP address is correct as I can access the web client from another device using that URL. What is strange, is that the Android client works when using an ng rok redirect. So I know it's possible, but I have no idea what I'm missing.
I apologize if anything is unclear, I have spent countless hours trying to get this working without ng rok because of latency issues, and am quite stuck now!
EDIT: I have also been able to confirm that this is only not working on the Android client. I am using the chat application to communicate between a Wear OS smart watch and an Android enabled VR headset (Pico Neo 3 Pro Eye). I am using a C# wrapper for the VR application, and this is able to connect using the above URL (http://LOCAL_IP_ADDRESS:3000). The only thing I'm doing differently is specifying the transport mode (which I have tried in the Wear OS client):
// From my Unity Application which works fine
var uri = new Uri("http://192.168.88.140:3000/");
socket = new SocketIOUnity(uri, new SocketIOOptions
{
Transport = SocketIOClient.Transport.TransportProtocol.WebSocket
});
SOLUTION EDIT: So after literally spending 30~40 hours on this issue, I finally figured out what was going wrong. The watch I was using, the Moto 360, could connect to Wi-Fi using its standalone Wi-Fi, or over the bluetooth connection to an Android phone (i.e., using the phone's Wi-Fi connection). After all this time, I realized that the Wi-Fi connection over bluetooth was being proxied, and so was unable to connect to a locally deployed server.
Disconnecting the bluetooth on the Moto 360 and forcing it to connect to the same Wi-Fi as my server, solved the XHR Poll Error!!
I'm trying to build an application that the communication will be done by a node.js server. This node server will receive messages from others peers.
My node.js code is:
var zmq = require('zmq'),
socket = zmq.socket('sub');
socket.bind('tcp://127.0.0.1:5556', function (err) {
if (err) {
console.log('Error: ', err);
throw err;
}
socket.on('message', function (envelope, blank, data) {
console.log(arguments);
});
socket.on('error', function (err) {
console.log(arguments);
});
});
In the other part of the system, there is a java server that should send messages for this server.
This is my java code:
Context context = ZMQ.context(1);
Socket publisher = context.socket(ZMQ.PUB);
publisher.connect("tcp://127.0.0.1:5556");
for (int request_nbr = 0; request_nbr < 10; request_nbr++) {
publisher.send("Hello");
}
For now, my java server is running locally and my node.js is running inside a docker with the port 5556 exposed.
I have success sending messages from the java server. But no message is received in my node.js server.
There is any problem in my ZeroMQ initialization?
Yes, there is a problem:
As defined in the ZeroMQ protocol-specifications, the SUB-Formal Scalable Communication Pattern archetype has an empty subscription list upon it's instantiation.
Empty SUB-side subscription is the cause:
Your SUB-side has to indeed subscribe to anything else ( be it at least a "" - yes - an empty string is enough, for starting receiving any and all messages, or may setup some problem/context-specific string(s), as TOPIC-filter, where each message will start to get tested for a presence of at least one of such TOPIC-s, and discarded ( not .recv()-ed or not promoted into the hands of .on( 'message', ... ) handler at all ).
Anyway, enjoy the ZeroMQ powers for the distributed computing!
I have this code. (Used it in other old project of mine, worked wonderfully)
SOCKET Connect(char * host, int port){
struct sockaddr_in sin = {0};
struct hostent * entry = 0;
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET){
return INVALID_SOCKET;
}
entry = gethostbyname(host);
if(entry == 0){
closesocket(s);
return INVALID_SOCKET;
}
sin.sin_addr = *((LPIN_ADDR)*entry->h_addr_list);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
// The process becomes dealocked after this line
if( connect(s,(const LPSOCKADDR)&sin,sizeof(SOCKADDR)) == SOCKET_ERROR){
closesocket(s);
return INVALID_SOCKET;
}
return s;
}
I started this morning working on a Delphi project using TTcpClient and Indy's TIdTcpClient wrappers and I noticed the process did not make any connections rather it just hung after calling connect. I then switched to C/C++ and tried with this code which does the same thing. After it hangs, there's no way to kill it (unless when it's being debugged where I had to exit the debugger). TaskManager, Process Explorer didn't do shit.
There are no threads or loops or whatever that may cause it to hang just this code and another function that writes to the socket after it connects.
When debugging with Visual Studio, after sometime there's a message (below)
Even Wireshark doesn't show anything at all. Restarted my computer and still the same problem.
So has anyone ever had this problem before?
Used compilers
Visual Studio 2010
Pelles-C
Delphi 7
OS : Windows 7 64 bit, Ultimate
Winsock Version: 2.2
Update:
So I thought I would getaway and switched to Java only to find out the same problem after a couple of times. What the hell is wrong here. The Java takes around 2 minutes to connect even on localhost. This simple code takes ~2 minutes during which java.exe can't be killed also.
long startTime = System.currentTimeMillis(), endTime;
Socket clientSock = new Socket("localhost",80); // running Apache on localhost
endTime = System.currentTimeMillis();
Log("Connection time " + (endTime - startTime) + " ms");
clientSock.close();
run:
Connection time 125088 ms
As for Java I did some searches and this problem was a bug in version 1 of the JDK but the change log showed it had been patched. But then again this happens in the underlying winsock library. WHY ? This program connects instantly and it also uses winsock: http://flatassembler.net/examples/quetannon.zip
So now I have to re-write 976 lines of JAVA in assembly just because of this? Help me out here people.
Since you are encountering the same problem in multiple wrappers that all ultimately delegate to Winsock, its safe to assume that this is an OS issue, not a coding issue. Something on your system has hosed your Winsock installation, or the OS is having networking problems in general, especially since a simple OS reboot did not clear the issue. Try using Windows' command-line netsh tool to reset both the TCP and Winsock subsystems, the command-line ipconfig tool to flush the DNS cache, reboot, and see if the problem continues.
On the coding side, you should implement a timeout on the connect() to avoid further deadlocks. There are two ways to do that:
Put the socket into non-blocking mode and then call select() if connect() returns a WSAEWOULDBLOCk error. If select() times out, close the socket.
Leave the socket in blocking mode and use a separate thread to manage the timeout. Call connect() in the thread, or run your timeout logic in the thread, it does not really matter, but if the timeout elapses while connect() is still running then you can close the socket, aborting connect(). This is the approach that TIdTCPClient uses.
Ok. For the JAVA part at least I solved it by using the following code based on the answer here Java Socket creation takes more time.
So basically the default timeout value is (possibly) huge.So what I did was set a 3 second timeout then once the timeout exception is thrown, the next call works instantly.
private static final int CONNECT_TIMEOUT = 3000; // 3 seconds
private static Socket AttemptConnection(String host, int port) {
Socket temp;
try {
temp = new Socket();
temp.connect(new InetSocketAddress(host, port), CONNECT_TIMEOUT);
return temp;
} catch (Exception ex) {
temp = null;
lastException = ex.getMessage();
return temp;
}
}
And somewhere in your code (at least in my app)
while ( (clientSock = AttemptConnection("localhost",80)) == null ){
Log("Attempting connection. Last exception: " + lastException);
try{Thread.sleep(2500);}catch(Exception ex){} /* This is necessary in my application */
}
So looking at this I think the fix to all the socket implementations (JAVA,Delphi, etc) is to set a small timeout value then connect again.
EDIT:
The root of the problem was found: I have a HIPS program (COMODO Firewall) running on my laptop. If COMODO's cmdagent.exe is active, it'll show me an alert of an outgoing connection to which I can accept/deny. If not, it will silently deny the connection, so therefore something becomes deadlocked in the low levels.I was worried my PC was effed up.
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.
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.