PHP Socket Programming Detailed
This article mainly introduces the PHP socket programming detailed, the need for friends can refer to the following
1. Pre-knowledge
It has been very rare to see how many people use the PHP socket module to do something, probably everyone put it in the context of scripting language, but in fact, PHP socket module can do a lot of things, including do ftplist,http post submission, SMTP commit, Group packages and make special message interactions (such as the SMPP protocol), WHOIS queries. These are the more common queries.
In particular, the PHP socket extension library can do things that are not much worse than c.
The socket connection function of PHP
1. Socket integrated in the kernel
This series of functions can only do the active connection can not implement the port monitoring related functions. And all socket connections only work in blocking mode before 4.3.0.
This series of functions includes
Fsockopen,pfsockopen
The specific information for these two functions can be queried by the Php.net user manual
They'll all return a resource number. For this resource, you can use almost any function that operates on a file to manipulate it, such as fgets (), fwrite (), fclose () etc. note that all functions follow the laws of these functions in the face of network traffic, such as:
Fread () reads up to length bytes from a file pointer handle. The function will stop reading a file when it is available, or (for a network stream) when it has been read by the length of bytes, or when it reaches EOF, depending on what kind of situation is encountered first.
It can be seen that for a network stream it is important to note that a complete package is stopped.
2, the PHP extension module with the socket function.
Php4.x later there is a extension=php_sockets.so on this module extension=php_sockets.dll,linux.
When this module is opened, it means that PHP has a powerful socket function, including listen ports, blocking and non-blocking mode switching, multi-client interactive processing, etc.
The list of functions for this series is listed in http://www.php.net/manual/en/ref.sockets.php
Have you ever seen this list? But unfortunately this module is also very young and many places are immature, the relevant reference documentation is very small: (
I am also in the study, so for the time being not specifically discussed it, only to give you a reference to the article
http://www.zend.com/pecl/tutorials/sockets.php
2. Using the PHP socket extension
Server-side code:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21st 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
/** * File name server.php * Server-side code * * @author Guisu.huang * @since 2012-04-11 * */ Ensure that the client is not timed out when connecting Set_time_limit (0); Set IP and port number $address = "127.0.0.1"; $port = 2046; When debugging, you can change the port to test the program! /** * Create a socket * af_inet= is IPv4 if IPv6 is used, the parameter is Af_inet6 * Sock_stream is the TCP type of the socket, and if it is UDP use Sock_dgram */ $sock = Socket_create (Af_inet, Sock_stream, sol_tcp) or Die ("Socket_create () failed due to:". Socket_strerror (Socket_last_error ()). "/n"); Blocking mode Socket_set_block ($sock) or Die ("Socket_set_block () failure is due to:". Socket_strerror (Socket_last_error ()). "/n"); Bind to socket port $result = Socket_bind ($sock, $address, $port) or Die ("Socket_bind () failed due to:". Socket_strerror (Socket_last_error ()). "/n"); Start listening. $result = Socket_listen ($sock, 4) or Die ("Socket_listen () failed due to:". Socket_strerror (Socket_last_error ()). "/n"); echo "ok\nbinding the socket on $address: $port ... "; echo "Ok\nnow ready-to-accept connections.\nlistening on the socket ... \ n"; Do {//Never stop the daemon It receives the connection request and invokes a child connection socket to handle the information between the client and the server $msgsock = socket_accept ($sock) or Die ("Socket_accept () Failed:reason:". Socket_strerror (Socket_last_error ()). "/n"); Read client data echo "Read client data \ n"; The Socket_read function reads the client data until it encounters the \n,\t or the/s character. The PHP script considers this character to be the input terminator. $buf = Socket_read ($msgsock, 8192); echo "Received msg: $buf \ n"; Data transfer writes the returned results to the client $msg = "Welcome \ n"; Socket_write ($msgsock, $msg, strlen ($msg)) or Die ("Socket_write () Failed:reason:". Socket_strerror (Socket_last_error ()). " /n "); Once the output is returned to the client, the parent/child socket should be terminated by the Socket_close ($msgsock) function Socket_close ($msgsock); } while (true); Socket_close ($sock); |
Client code:
?
1 2 3 4 5 6 7 8 9 11 + All /+ //+ + |
!--? php /** * File name:client.php * Client code * * @author Guisu.huang * @sin CE 2012-04-11 */ Set_time_limit (0); $host = "127.0.0.1"; $port = 2046; $socket = socket_create (Af_inet, Sock_stream, sol_tcp) or Die ("Could not create socket\n");//Create a socket $connection = Socket_connect ($socket, $host, $port) or Die ("Could not connet server\n");//connection Socket_w Rite ($socket, "hello socket") or Die ("Write failed\n"); Data transfer sends a message to the server while ($buff = Socket_read ($socket, 1024x768, Php_normal_read)) { Echo ("Response was:". $buff. "\ n"); } Socket_close ($socket); |
To start the server using the CLI:
PHP server.php
Note here the Socket_read function:
The optional type parameter is a named constant:
Php_binary_read-Use the system recv () function. Used to read the security of binary data. (in php> "default = 4.1.0)
Php_normal_read-read stop in \ n or \ r (default in PHP <= 4.0.6)
For parameter php_normal_read, if the server's response result is not \ n. Cause socket_read (): Unable to read from socket
3. PHP Socket Internal Source code
From the internal source of PHP, PHP provides socket programming is to add a layer outside the Socket,bind,listen function, so that it is more simple and convenient to call. But some business logic programs need to be implemented by programmers themselves.
Below we use the Socket_create source code implementation to explain the internal implementation of PHP.
We have mentioned that the socket for PHP is implemented in an extended manner. In the Ext directory of the source code, we find the sockets directory. This directory contains the PHP implementation for the socket. Direct Search for Php_function (socket_create), the implementation of this function was found in the sockets.c file. The code is as follows:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21st 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* {{{proto resource socket_create (int domain, int type, int protocol) U Creates an endpoint for communication in the domain specified by domain, of type specified by type */ Php_function (Socket_create) { Long arg1, arg2, Arg3; Php_socket *php_sock = (php_socket*) emalloc (sizeof (php_socket)); if (Zend_parse_parameters (Zend_num_args () tsrmls_cc, "lll", &arg1, &arg2, &arg3) = = FAILURE) { Efree (Php_sock); Return } if (arg1! = Af_unix #if Have_ipv6 && arg1! = Af_inet6 #endif && arg1! = af_inet) { Php_error_docref (NULL tsrmls_cc, e_warning, "Invalid socket domain [%LD] specified for argument 1, assuming Af_inet", arg1 ); Arg1 = af_inet; } if (Arg2 > 10) { Php_error_docref (NULL tsrmls_cc, e_warning, "Invalid socket type [%LD] specified for argument 2, assuming Sock_stream", AR G2); Arg2 = Sock_stream; } Php_sock->bsd_socket = socket (arg1, arg2, ARG3); Php_sock->type = arg1; if (Is_invalid_socket (Php_sock)) { Sockets_g (last_error) = errno; Php_error_docref (NULL tsrmls_cc, e_warning, "Unable to create socket [%d]:%s", errno, Php_strerror (errno tsrmls_cc)); Efree (Php_sock); Return_false; } Php_sock->error = 0; php_sock->blocking = 1; 1257,1-8 61% Zend_register_resource (Return_value, Php_sock, Le_socket); } |
The Zend API actually wraps the C function socket for use by PHP. In the socket programming of C, we initialize the socket using the following method.
?
1 2 3 4 5 |
Initialize socket if ((SOCKET_FD = socket (af_inet, sock_stream, 0)) = = = 1) { printf ("Create Socket Error:%s (errno:%d) \ n", Strerror (errno), errno); Exit (0); } |
4. Socket function
Function Name Description
Socket_accept () accepts a socket connection
Socket_bind () binds the socket to an IP address and port
Socket_clear_error () Clears the socket error or the last error code
Socket_close () Close a socket resource
Socket_connect () Start a socket connection
Socket_create_listen () Open a socket listener on the specified port
Socket_create_pair () produces a pair of undifferentiated sockets into an array
Socket_create () produces a socket equivalent to a data structure that produces a socket
Socket_get_option () Get socket options
Socket_getpeername () Gets the IP address of a remote similar host
Socket_getsockname () Gets the IP address of the local socket
Socket_iovec_add () Add a new vector to a scatter/aggregate array
Socket_iovec_alloc () This function creates a IOVEC data structure that can send the received read and write
Socket_iovec_delete () Delete an assigned Iovec
Socket_iovec_fetch () returns the data for the specified Iovec resource
Socket_iovec_free () releasing a Iovec resource
Socket_iovec_set () Sets the new data value of the Iovec
Socket_last_error () Gets the last error code for the current socket
Socket_listen () listens for all connections by the specified socket
Socket_read () reads the specified length of data
SOCKET_READV () reads data from a scatter/aggregate array
SOCKET_RECV () end data from socket to cache
Socket_recvfrom () accepts data from the specified socket, if not specified, the default current socket
Socket_recvmsg () receive messages from Iovec
Socket_select () multi-channel selection
Socket_send () This function sends the data to the connected socket
SOCKET_SENDMSG () Send message to socket
Socket_sendto () sends a message to the socket at the specified address
Socket_set_block () set as block mode in socket
Socket_set_nonblock () set to non-block mode in socket
Socket_set_option () Set socket options
Socket_shutdown () This function allows you to close a read, write, or specified socket
Socket_strerror () returns a detailed error for the specified error number
Socket_write () write data to the socket cache
Socket_writev () write data to a scatter/aggregate array
5. PHP Socket Impersonation Request
We use Stream_socket to simulate:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21st 22 23 24 25 26 27 28 29 30 31 |
/** * * @param $data = array=array (' key ' =>value) */ function post_contents ($data = Array ()) { $post = $data? Http_build_query ($data): "; $header = "post/test/http/1.1". "\ n"; $header. = "user-agent:mozilla/4.0+ (COMPATIBLE;+MSIE+6.0;+WINDOWS+NT+5.1;+SV1)". "\ n"; $header. = "Host:localhost". "\ n"; $header. = "Accept: */*". "\ n"; $header. = "referer:http://localhost/test/". "\ n"; $header. = "Content-length:". Strlen ($post). "\ n"; $header. = "content-type:application/x-www-form-urlencoded". "\ n"; $header. = "\ r \ n"; $DDD = $header. $post; $fp = Stream_socket_client ("tcp://localhost:80", $errno, $errstr, 30); $response = "; if (! $fp) { echo "$errstr ($errno) \ n "; } else { Fwrite ($fp, $DDD); $i = 1; while (!feof ($fp)) { $r = fgets ($fp, 1024); $response. = $r; Handle this line } } Fclose ($FP); return $response; } |
Note that the above procedure may enter a dead loop;
This PHP feof ($fp) needs to be noted, let's analyze why into the dead loop.
?
1 2 3 4 |
while (!feof ($fp)) { $r = fgets ($fp, 1024); $response. = $r; } |
In fact, feof is reliable, but when combined with the Fgets function, you have to be careful. A common practice is to:
?
1 2 3 4 5 |
$fp = fopen ("MyFile.txt", "R"); while (!feof ($fp)) { $current _line = fgets ($FP); Further processing of results to prevent entry into the dead loop } |
When working with plain text, Fgets gets the last line of characters, and the result returned by the FOEF function is not true. The actual operating procedure is as follows:
1) while () continues the loop.
2) Fgets Gets the string of the penultimate line
3) feof return False, go to the next loop
4) Fgets get the last row of data
5) Once the Fegets function is called, the feof function still returns false. So continue the loop.
6) Fget tries to get another row, but the actual result is empty. The actual code is unaware of this, trying to deal with another line that does not exist at all, but Fgets is called, and the result of feof is still false.
7) .....
8) Enter the dead loop
http://www.bkjia.com/PHPjc/1004548.html www.bkjia.com true http://www.bkjia.com/PHPjc/1004548.html techarticle PHP Socket Programming Details This article mainly introduces the PHP socket programming in detail, the need for friends can refer to the next 1. Preliminary knowledge it has been very rare to see how many people use the PHP socket module to ...