davidp Posted January 22, 2008 Share Posted January 22, 2008 Wow...this is a pretty mind boggling bug I am having. I am using the socket API in PHP to connect to a server called GeoNames and retrieve some information. I formulate my request as such: //Now we start to set up our sockets. We will be using port 80, and we specify the host and the path we want. $service_port = 80; $address = gethostbyname('ws.geonames.org'); $path = '/countrycodeJSON?lat='.$lat.'&lng='.$lon; //$path = '/findNearbyPlaceNameJSON?lat='.$lat.'&lng='.$lon; //Create a socket for us to use $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } //Connect to the host $result = socket_connect($socket, $address, $service_port); if ($result === false) { echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; } //Now that we have a socket connected to the host, we need to form our HTTP request. $in = "GET ".$path." HTTP/1.1\r\n"; $in .= "Accept: */*\r\n"; $in .= "Host: ws.geonames.org\r\n"; $in .= "\r\n"; $out = ''; //Now we send our HTTP request to the host socket_write($socket, $in, strlen($in)); It is pretty simple socket code that anybody familiar with sockets should understand. Here is the fun part: when I run this same PHP script on my own computer, and then run it again on a different machine in the Computer Science labs on campus at my university, I get two different responses from the GeoNames server. Let me explain how I retrieve the response. I wrote this code to retrieve the response initially: //Now we read a reply while ($out = socket_read($socket, 2048)) { $out = trim ( $out ); $len = strlen ( $out ); if ( $out[$len - 1] == '0' ) break; } Running this code on my machine, I get a response from the GeoNames server formatted like this: HTTP/1.1 200 OK Date: Tue, 22 Jan 2008 06:07:42 GMT Server: Apache/2.0.54 (Linux/SUSE) Cache-Control: no-cache Vary: User-Agent Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Set-Cookie: JSESSIONID=68E951A10BA522A56C89906FBEC7DC68; Path=/ Connection: Keep-Alive 25 {"countryName":"","countryCode":""} 0 As you can see, there is no "Content-Length" header. I figured out however, that the "25" contained right at the beginning of the content is actually the hexidecimal representation of the number of bytes contained in the content. That, then, is essentially this other server's way of telling me the content length. Then the "0" tells me when I have reached the end of the response. So...that is what happens on my own computer when I run this PHP script. Now, I also coded up a 2nd way of receiving the response from the GeoNames server that is much more C/C++ in style. Here it is: $bytesReceived = -1; $httpResponse = ""; $responseMessage = ""; while ( $bytesReceived != 0 ) { $httpResponse = ""; $bytesReceived = socket_recv ( $socket, $httpResponse, 2048, 0 ); $responseMessage .= $httpResponse; } This is how I normally handle responses using the socket API in C/C++, so I wanted to try it in PHP. Unfortunately, when I tested this on my own machine, it entered an infinite loop. Soooo.... I then transferred my PHP script to a machine on campus in our CS labs, and I ran it there (using method 1 of retrieving a response from the GeoNames server). Doing this...it crashed. Well, it didn't crash, but I simply didn't receive ANY response from the GeoNames server. The response came back blank. I decided to implement method 2 of retrieving a response (the C/C++ way of doing things), and I tested that way on that machine. I got a response perfectly! (No infinite loop occurred like had happened on my machine). However....the response is different than the response I receive on my own machine. Here is the response I get when I run the script on the CS lab machine: HTTP/1.0 200 OK Date: Tue, 22 Jan 2008 06:01:27 GMT Server: Apache/2.0.54 (Linux/SUSE) Cache-Control: no-cache Vary: User-Agent Content-Type: application/json;charset=UTF-8 Set-Cookie: JSESSIONID=D3608996B6BF4822F52FB1AA08E40A99; Path=/ X-Cache: MISS from firewall.cs.byu.edu X-Cache-Lookup: MISS from firewall.cs.byu.edu:3128 Via: 1.0 firewall.cs.byu.edu:3128 (squid/2.6.STABLE6) Proxy-Connection: close {"countryName":"Kazakhstan","countryCode":"KZ"} As you can see, for some reason the connection has been downgraded from HTTP/1.1 to HTTP/1.0. Also, there is still no "Content-Length" header, and the number contained at the beginning of the content that acted as a content-length identifier does not exist anymore! And there is no "0" to signal the end of the response like there was when I ran it on my own machine! So my question is: How can the two HTTP responses be so different? Is it a factor of the differences in my PHP code when I retrieve the responses? Why does the C/C++ style of doing things enter an infinite loop on my own machine, but work perfectly on another machine? And vise-versa for the first method I used of retrieving a response? I don't understand exactly what is going wrong here. Quote Link to comment https://forums.phpfreaks.com/topic/87177-php-sockets-getting-2-different-responses/ Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.