I have been searching Google for a while, but the problem I am running into is I am not exactly sure what it is I need to be searching for. (Searching for PHP C++ communication doesn't seem to be what I need) I am basically developing a c++ plugin for a game server, and I would like to create a web interface that can pass/pull data to and from the C++ plugin. The game already uses an RCON port for remote administrative access, but I stumbled across a header for the Network interface they use, so I assume I could use this.
My problem is I am not very familiar with using sockets. I assume I will basically need to open a socket in C++ and leave it listening, and then in the PHP, connect to that socket, pass the data, and close it.
Here is the interface...
http://www.ampaste.net/m2f6b6dbc
I am mostly just going to be pulling information like current list of connected players, names, and scores. And passing commands to restart the server, shut it down, etc.
Any help would be great, thanks!
You could try Thrift. It was written by the engineers at Facebook, and it's now an Apache project.
Thrift is a software framework for scalable cross-language services development. It combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, and OCaml.
Link: http://incubator.apache.org/thrift/
In a nutshell it does exactly what you're trying to do. It makes it easy for different languages to communicate with each other. Rather than trying to come up with some socket based protocol for communication, you can call a function in PHP like this:
$game->getScores();
And it automatically plugs into a function named getScores in your C/C++ program. The only drawback is it can be a bit of a pain to configure correctly.
I'd dare to recommend to use some standard means of distributed components communication, for example, XML RPC. There are libraries for both PHP and C++: http://en.wikipedia.org/wiki/XML-RPC#Implementations
This approach will keep you from reinventing the wheel during communication protocol implementation, and will make further maintenance cheaper.
I assume I will basically need to open a socket in C++ and leave it listening
err, yes, that's the description I'd give to my 12 year-old daughter - but if you're going to have more than one client connecting its a bit more involved. Especially if you are bolting the code onto an existing server. So have a read of the socket programming FAQ.
You do need to define a protocol of how data will be represented when travelling across the socket. THere are lots of 'standard methods - but sometimes things like CORBA / SOAP etc can just be overkill and more effort than starting from scratch.
If you are bolting code ontp an existing server, life will be a lot simpler if you use the current socket and extend the protocol if necessary.
There are 3 models for writing a socket server - the code snippet you provided does not seem to include details of which you are currently working with:
forking server (may split threads rather than processes)
single-threaded server
socketless server
forking server
An instance of the server is started (call it p1), calling setsid()
p1 starts listening on the relevant socket
a client tries to connect
p1 forks to create p2
p2 then accepts the connection and starts conversing with the client
p1 continues to listen for further connections
p2 exits when the connection closes
There are variations of this - p2 may accept further connections, p1 might fork prior to a connection coming in)
single-threaded
An instance of the server is started, calling setsid()
it starts listening for a connection, and creates an array of the sockets in use (including the initial one)
socket_select() is used to identify activity from any of the sockets
when a client connects, the connection is accepted and added to an array of connections
whenever socket_select() returns activity on one of the sockets, the server generaets an appropriate response / closes the socket / binds the new connection
socketless server
some process (e.g. inetd) handles all the socket stuff
when a client connects, this other server starts an instance of your program and binds the socket I/O to the STDIN/STDOUT of your program
when your program exits, the other process closes the socket (if its still open) and handles the clean up (e.g. if it is implemented as a forking server, then the spawned process may end)
What it appears you want to google is C++ client / server. There are two approaches I could suggest here.
First, would be to make a very basic HTTP protocol server so that your php script can simply go to http://yourip/ and send your commands through the POST variables. You can find an example of a C++ Web Server at: https://stackoverflow.com/questions/175507/c-c-web-server-library
The second approach which allows a lot more flexibility is make up your own basic protocol and use PHP's SOCKETS to connect to the server and send commands. You can find an example of a C++ client / server application at http://www.codeproject.com/KB/IP/client_server_socket.aspx. Keep in mind, for the C++ end, you are only concerned about the Server part. You can find a basic PING client in PHP, using sockets, at the following URL: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=8&txtCodeId=1786. There are also classes out there to handle most of the protocol part, though I am not aware of any that work for both languages.
Please note I have not tested any of the codes I linked to. I simply found them on google.
A good place to start would be http://php.net/manual/en/book.sockets.php.
Basically, you're going to create another remote administration port and method for PHP to connect. Naturally, if your going to only be accepting web communication from one IP, that's a good way to secure it (check and allow access to only the one IP which will connect). However, you will need the C++ server to listen on a (secure?) port and have PHP connect to it (as long as host allows it).
So overall, if you already have a server running, this should be simple from the C++ side. All you need to do from the PHP side is really research connecting to different servers and passing information along (which PHP is more than capable of doing efficiently)
But, this is obviously an alternative to the poster up 2. I personally enjoy (in many cases) "reinventing the wheel" so to speak as to be able to manage my own work. But of course, that is not always efficient by cost or otherwise.
Good luck!
Related
I have a question regarding the titled question. So, I'm attempting to create a program which passes data/requests for data between a program in C++ and a PHP site running off of an Apache web server.
I've been researching Socket communications, but I'm not understanding the concept. I understand how to create a socket in PHP, and another in c++, and I have them running using a test application. But only individually, not talking to each other OR talking to my web server (the PHP is not on the server at the moment, it is on a different server). So how does this work? From my understanding, you need one to be listening to a port number, and the other one to send something to that command.
Ideally, I would prefer not to use any libraries to help me achieve this. I know this question has been asked many times before, but I'm still getting nowhere.
Could someone provide an explanation of how the above works, or links to a question on here/elsewhere that may be of help? Or if there is a better method of doing this than using sockets? They will be talking to each other a lot, and speed maybe an issue.
Edit, further explanation:
Web server: I'm running an Apache web server. The PHP script is located on this server.
C++ Location: While testing, my c++ application is stored on the same Raspberry Pi that the web server is running on. In the real application, my C++ application will still be stored on the same device (but it won't be a Raspberry Pi - still Linux based though).
Communication: The PHP script will need to be triggered to do things by the C++ script, and vice versa. They will need to both need to pass data (common data structures, but they could be fairly large) each way (so both need to be able to send and receive data).
I think the easiest way is:
1) PHP -> C++ : tcp
2) C++ -> PHP : http
Will try to explain.
1) To take something from C++ app PHP connects to that app using stream_socket_client function. C++ app is listening on host and port using socket, bind and listen functions. As soon as connection arrives C++ app accept it and then in a separate std::thread serves it (recv to get request, send to send response). How to socket.
2) As PHP is working under Apache Web Server, I think the easiest way is use of libcurl library to make HTTP request from C++ app. How to curl.
Another approach could be SOAP or REST Web Services. On both sides, you could provide a SOAP Web Service to exchange data or to call remote functions. On C++-side, you could use Apache Axis to provide a SOAP Server. On PHP side, you can use the build-in SOAPServer class (http://php.net/manual/de/class.soapserver.php).
With SOAP you simply would exchange XML-based messages between both applications over HTTP / HTTPS. With this approch, both applications can trigger each other and exchange data.
Adding to the answer of Ben Schnarr, I think probably the most elegant and easy solution would be to make the C++ program a client for web services implemented in the PHP code. Using sockets directly would force you to have an additional protocol over it to represent the data being transmitted (unless the data is trivially simple, like a stream of ASCII text), which would be a bit like reinventing the wheel.
I'm partial to REST+JSON, because they are simple to implement and use, and very powerful. In contrast, SOAP is quite complex, heavy in resources, and brittle, especially if you use it with C++. One popular implementation I've already used, for instance, would force you to recompile your code every time you change the layout of any of the messages, even if the server is adding a field that the client won't use.
On the PHP side, it's quite easy - it already has all the infrastructure you need. On the C++ program, the minimum you'll need would be an HTTP client library and a JSON codec. I use libcurl for the first (by far the most popular) and jsoncpp for the latter, but there are other options for both. More recently, some libraries appeared with the whole package, but I hadn't had the chance to use them yet. Some examples:
restclient
REST SDK
Restbed
I recommend you to use Unix Sockets
For c++ check this: http://www.linuxhowtos.org/C_C++/socket.htm
For php check this: stream_socket_client
You can pass info internally from both processes.
Hope you can solve it, don't give up.
A SOAP solution could be something that solve the problem, but in my opinion it complicates a lot the application deployment.
You could go down a few levels and work directly with XML-RPC.
Here you have two interesting links, that shows how to implement the client and the server in both languages.
XML-RPC for C++
XML-RPC for PHP
There are other implementatios of XML-RPC for C++ (I have not used this approach with PHP, so I don't know others alternatives), don't stick with only one, try with others and use what you feel more comfortable with.
If you need some guidance on what stas told you then I suggest you look at
http://us2.php.net/manual-lookup.php?pattern=fsock&src={referrer:source?}
http://us2.php.net/manual-lookup.php?pattern=socket&src={referrer:source?}
In C++ you'll want to create a TCP listener that accepts commands (clearly you'll want to put some method of validation in),
then use PHP to open a connection (use fsock or socket your choice - fsock is easier), and write data to your C++ listener. It's ezpz
//updating with some example code
// protocol://ip, port, $errno, $errstr, $timeout
$fp = fsockopen("tcp://ip", 1337, $errno, $errstr, 30);
if(!$fp) die('failed connection or something');
//write something
fwrite($fp, "stuffs to write");
// get a reply?
while (!feof($fp)) {
echo fgets($fp, 128); // where 128 is size
}
I want to build a game in AS3 and do most of the logic in PHP/MySQL since I'm more experienced in PHP than in any other language that was recommended for it like JAVA.
I've read a lot about that PHP is not a good option for a PHP socket server. The main reason was that it will not manage to handle more than about 1000 clients.
But I never found a good reply why actually it is like that? Is the PHP process crashing after it? Is it an option to set up for example 2 socket servers on different ports? Will it handle about 2000 clients then? Or still not?
If you know AS, I would actually recommend either Java or Node, actually. AS3 is very similar to both Java and JavaScript (some differences), which would make the conversion pretty painless. The magic you have to decide on is how many messages go through each of your clients per second.
If the load is light, prefer Node. If the load is heavy, prefer Java.
If, however, you want to stick to PHP, you will need multiple game instances running from CLI (NOT from Apache). You can then connect to them through standard sockets in any way you like. This is easy to do.
The hard bit is to synchronize all the instances. You can do so by having them all connect to an instance that is solely dedicated to relaying messages to the servers, or have them connect between each other. Game comms theory books and tutorials will come in handy on how to do this.
Your other issues will be, if using PHP, amongst others:
The socket connection limit per daemon
Single-threaded nature of PHP
Caching
Building an evented multi-client socket interface from something that, inherently, does not have this
PHP is at a severe disadvantage compared to Java on this. It is, however, possible.
I want to create http socket connection for server in php for multiple client . how can I do that ? I need some resource .
First I was trying to create server in java .I create a server in java . And trying to reach from android application .But server can't find any client.But when I create client in java .It was working. How can I solve that problem ???
Take a look at this article:
Writing Socket Servers in PHP by Zend
Also give a try with Google:
http://www.google.com/search?aq=0&oq=php+socket+server+mul&sourceid=chrome&ie=UTF-8&q=php+socket+server+multiple+clients
Personally I think this would be a pretty bad idea, as already mentioned it lacks Threading and it's Socket support (imo) isn't really that adaptable.
The only plus side is that you can use fork to fork off another PHP process to handle a client, but you're getting very complex.
Another language would be much more suited for this type of development.
Note that even if you did do this in PHP, you'd probably have to rely on external services anyway, and possibly even end up writing at least some code in another language anyway.
You're trying to use PHP to do what? Mind you, I like PHP and work with it almost every day, but please do remember PHP in and on itself is based on request and response, and not very suitable for long running processes. In a manner of exercise, it might be interesting, but if you're trying to write a webserver from scratch using PHP, you might want to reconsider your choice of language.
That said, you can create a socket acting as a server, and listen to incoming packets. I do still think you're reinventing the wheel though.
though i love php and java, i wrote my socket servers in c++ running under lamp in an amazon ec2 cloud server. it is very, very simple to code and debug and safe and you can practically just copy/paste examples.
in the long run, i will probably develop a java solution because of portability and scalability, but the initial effort to get a c++ solution working is just so much less than implementing a java solution...
the first thing you must ascertain (find out) is whether your server allows you to open custom ports. amazon ec2 does and at this point in time (feb13), can be used for free for 12 months.
so, this is for you if you are in a hurry:
this here set of examples has all that you need to be up and running in no time.
Judging from the question title (the rest only makes it more confusing) you could use an existing package like http://pear.php.net/package/HTTP_Server to implement a webserver in PHP. It already contains all the socket code to accept client connections and stuff.
So what i have to do to find the server from different client
"Finding" is too broad a topic. Depends on your actual setting. On a LAN there are some protocols for discoverability. Otherwise you should just rely on a fixed machine name and port number for your instantiated server. You can connect to it as e.g. http://localhost:8007/ or whatever you've predefined.
Python, Perl and PHP, all support TCP stream sockets. But exactly how do I use sockets in a script file that is run by a webserver (eg Apache), assuming I only have FTP access and not root access to the machine?
When a client connects to a specific port, how does the script file get invoked?
Does the script stay "running" for the duration of the connection? (could be hours)
So will multiple "instances" of the script be running simultaneously?
Then how can method calls be made from one instance of the script to another?
Scripting languages utilize sockets exactly the same way as compiled languages.
1) The script typically opens and uses the socket. It's not "run" or "invoked" by the socket, but directly controls it via libraries (typically calling into the native C API for the OS).
2) Yes.
3) Not necessarily. Most modern scripting langauges can handle multiple sockets in one "script" application.
4) N/A, see 3)
Edit in response to change in question and comments:
This is now obvious that you are trying to run this in the context of a hosted server. Typically, if you're using scripting within Apache or a similar server, things work a bit differently. A socket is opened up and maintained by Apache, and it executes your script, passing the relevant data (POST/GET results, etc.) to your script to process. Sockets usually don't come into play when you're dealing with scripting for CGI, etc.
However, this typically happens using the same concepts as mod_cgi. This pretty much means that the script running is nothing but an executable as far as the server is concerned, and the executable's output is what gets returned to the client. In this case, (provided you have permissions and the correct libraries on the server), your python script can actually launch a separate script that does its own socket work completely outside of Apache's context.
It's (usually) not a good idea to run a full socket implementation directly inside of the CGI script, however. CGI will expect the executable to run to completion before it returns results to the client. Apache will sit there and "hang" a bit waiting for this to complete. If you're launching a full server (especially if it's a long running process, which they tend to be), Apache will think the script is locked, and probably abort, potentially killing the process (configuration specific, but most hosting companies do this to prevent scripts from taking over CPU on a shared system).
However, if you execute a new script from within your script, and then return (shutting down the CGI executable), the other script can be left running, working as a server. This would be something like (python example, using the subprocess library):
newProccess = Popen("python MyScript", shell=True)
Note that all of the above really depends a bit on server configuration, though. Many hosting companies don't include some of the socket or shell libraries in their scripting implementations specifically to prevent this, so you often have to revert to making the executable in C. In addition, this is often against terms of service for most hosting companies - you'd have to check yours.
As a prior answer notes, scripting languages have operate in this regard in exactly the same way as compiled programs. Where they differ (potentially) is in the API that they use. The operating system (Windows or Unix-based) offers an API (e.g., BSD sockets) that compiled programs will call directly (typically). Interpreted languages like PHP or Python may offer a different API such as Python's socket API which may simplify some parts of the underlying API.
Given any of these APIs, there are many ways in which the actual handling of an incoming TCP connection can be structured. A great and detailed overview of such approaches is available on the c10k webpage: http://www.kegel.com/c10k.html -- in particular, the section on IO strategies. In short, the choice of answers to your question is up to the programmer and may affect how the resulting program performs under load.
To focus on your specific questions:
Many server programs are started before the connection and are running to listen for incoming connections. A special case is inetd which is a superserver: it listens for connections and then hands off those connections to programs that it starts (specified in a config file).
Typically, yes, the script remains running for the duration of the connection. However, depending on the larger system architecture, the script could conceivably pass the connection off to another program for handling and then exit.
This is a choice, again as enumerated on the c10k page.
This is another choice; operating systems offer a variety of Interprocess Communication (IPC) mechanisms to programs.
The only way I can make sense of what you're asking is if you use inetd or a similar meta-server, which is configured to invoke your "service a single client" program for a specific listening port, forwarding your "single client servicer" program's stdin/stdout to the remote client.
If that's the case:
1) inetd runs it
2) yes
3) yes
4) named pipes are one possibility
When a client connects to a specific
port, how does the script file get
invoked?
The script should be already invoked in order to receive any connects from any client. You will need script to be hanging on there forever (infinie loop) and setup Apache not to kill it on timeout. Basically, PHP is not a good choice for writting server applications. Why do you need this?
Is it possible to implement a p2p using just PHP? Without Flash or Java and obviously without installing some sort of agent/client on one's computer.
so even though it might not be "true" p2p, but it'd use server to establish connection of some sort, but rest of communication must be done using p2p
i apologize for little miscommunication, by "php" i meant not a php binary, but a php script that hosted on web server remote from both peers, so each peer have nothing but a browser.
without installing some sort of
agent/client on one's computer
Each computer would have to have the PHP binaries installed.
EDIT
I see in a different post you mentioned browser based. Security restrictions in javascript would prohibit this type of interaction
No.
You could write a P2P client / server in PHP — but it would have to be installed on the participating computers.
You can't have PHP running on a webserver cause two other computers to communicate with each other without having P2P software installed.
You can't even use JavaScript to help — the same origin policy would prevent it.
JavaScript running a browser could use a PHP based server as a middleman so that two clients could communicate — but you aren't going to achieve P2P.
Since 2009 (when this answer was originally written), the WebRTC protocol was written and achieved widespread support among browsers.
This allows you to perform peer-to-peer between web browsers but you need to write the code in JavaScript (WebAssembly might also be an option and one that would let you write PHP.)
You also need a bunch of non-peer server code to support WebRTC (e.g. for allow peer discovery and proxy data around firewalls) which you could write in PHP.
It is non-theoretical because server side application(PHP) does not have peer's system access which is required to define ports, IP addresses, etc in order to establish a socket connection.
ADDITION:
But if you were to go with PHP in each peer's web servers, that may give you what you're looking for.
Doesn't peer-to-peer communication imply that communication is going directly from one client to another, without any servers in the middle? Since PHP is a server-based software, I don't think any program you write on it can be considered true p2p.
However, if you want to enable client to client communications with a php server as the middle man, that's definitely possible.
Depends on if you want the browser to be sending data to this PHP application.
I've made IRC bots entirely in PHP though, which showed their status and output in my web browser in a fashion much like mIRC. I just set the timeout limit to infinite and connected to the IRC server using sockets. You could connect to anything though. You can even make it listen for incoming connections and handle them.
What you can't do is to get a browser to keep a two-way connection without breaking off requests (not yet anyways...)
Yes, but its not what's generally called p2p, since there is a server in between. I have a feeling though that what you want to do is to have your peers communicate with each other, rather than have a direct connection between them with no 'middleman' server (which is what is normally meant by p2p)
Depending on the scalability requirements, implementing this kind of communication can be trivial (simple polling script on clients), or demanding (asynchronous comet server).
In case someone comes here seeing if you can write P2P software in PHP, the answer is yes, in this case, Quentin's answer to the original question is correct, PHP would have to be installed on the computer.
You can do whatever you want to do in PHP, including writing true p2p software. To create a true P2P program in PHP, you would use PHP as an interpreted language WITHOUT a web server, and you would use sockets - just like you would in c/c++. The original accepted answer is right and wrong, unless however the original poster was asking if PHP running on a webserver could be a p2p client - which would of course be no.
Basically to do this, you'd basically write a php script that:
Opens a server socket connection (stream_socket_server/socket_create)
Find a list of peer IP's
Open a client connection to each peer
...
Prove everyone wrong.
No, not really. PHP scripts are meant to run only for very small amount of time. Usually the default maximum runtime is two minutes which will be normally not enough for p2p communication. After this the script will be canceled though the server administrator can deactivate that. But even then the whole downloading time the http connection between the server and the client must be hold. The client's browser will show in this time its page loading indicator. If the connection breakes most web servers will kill the php script so the p2p download is canceled.
So it may be possible to implement the p2p protocol, but in a client/server scenario you run into problems with the execution model of php scripts.
both parties would need to be running a server such as apache although for demonstration purposes you could get away with just using the inbuilt php test server. Next you are going to have to research firewall hole punching in php I saw a script i think on github but was long time ago . Yes it can be done , if your client is not a savvy programmer type you would probably need to ensure that they have php installed and running. The path variable may not work unless you add it to the system registry in windows so make sure you provide a bat file that both would ensure the path is in the system registry so windows can find it .Sorry I am not a linux user.
Next you have to develop the code. There are instrucions for how hole punching works and it does require a server on the public domain which is required to allow 2 computers to find each others ip address. Maybe you could rig up something on a free website such as www.000.webhost.com alternatively you could use some kind of a built in mechanism such as using the persons email address. To report the current ip.
The biggest problem is routers and firewalls but packets even if they are directed at a public ip still need to know the destination on a lan so the information on how to write the packet should be straight forwards. With any luck you might find a script that has done most of the work for you.