socket与curl

来源:互联网 发布:如何评价李沁长相知乎 编辑:程序博客网 时间:2024/06/05 04:07
Socket是什么?能干什么?长什么样?大致的原理是什么?我想还是给出实例来最好理解。
在这里,我还是用java来实现一个socket的服务端与客户端(你也可以用任何其他支持socket操作的语言来实现),然后用php来做为客户端请求该套接字。如下图所示,在服务器端使用socket开了一个服务,端口是8001,那么我就可以建立多个客户端来进行连接。在客户端,我向该socket发送一条消息,服务器端在收到了我的消息后,会根据情况进行一定的处理,返回给客户端,同时在服务器端打印所有收到的消息。
s1.jpg
    
从图1,我们看到服务器端和客户端都采用java实现,在图一的中间第二张图那里,我们看到,一旦我开启了服务器端,那么我这个服务就会被注册到windows的网络服务中,端口为8001,为了让你确信,我们可以用netstat命令来打印本机各端口的网络连接情况,在打印列表里,可以看到此服务已经被注册了。一旦有客户端连接此socket,操作系统就会为客户端自动分配一个随机端口来和服务器端8001端口进行通讯。
既然此服务已经被注册到操作系统中,那么其实此服务和你的QQ,FTP等实际上是一个级别的了,你可以用它来做太多太多的事情。为了验证一下,我们呢可以使用telnet来连接它。
s2.JPG
   由于socket是开放的,透明的,一旦运行,也就是说任何可以操作socket的语言都可以访问这个开放的服务,图一是使用java来访问socket,我们也可以使用php,甚至js(HTML5的新特性http://dev.w3.org/html5/websockets/)来访问此服务。
例七:Php端代码如下:
<?php
$sock = fsockopen("192.168.0.2", 8001, $errno, $errstr,1);
if (!$sock)
{
echo "$errstr ($errno)<br/>\n";
}else{
//socket_set_blocking($sock,false);
fwrite($sock, "senddata....\r\n");//注意:数据末尾需要加上"\r\n"来提交此请求数据,否则可能将无法获取服务端的回应,即使刷新缓冲也无效,这样就只有等到此连接关闭时才能获取到回应。
fwrite($sock, "end\r\n"); //使用end命令终止此客户端连接
while (!feof($sock)) {
echo fread($sock, 128);
flush();
ob_flush();
sleep(1);
}
fclose($sock);
}
运行后,结果如下:
s3.JPG
想要知道更多细节,可以使用IRIS抓包软件。
   好了,看了这么多演示,我想你对socket应该能有一个比较直观的认识了吧。现在我来总结一下socket是个神马东东。翻开百度百科,可以看到如下定义:“作为4BDSUNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。”所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。说白了就是一种通信机制。它类似于银行,电信啊这些部分的电话客服部门。你打电话的时候,那边会分配置一个人回答你的问题,客服部门就相当于socket的服务器端了,你这边呢就相当于客户端了,在和你通话结束前,如果有人在想找和你通话的那个说话,是不可能的,因为你在和他通信,当然客服部门的电话交换机也不会重复分配。
我们可以来看一个socket函数的原型定义:
SOCKET socket( int af, int type, int protocol );
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET,对于unix,可建立本地socket;
第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM;
第三个参数指定应用程序所使用的通信协议。
要想深入到socket的内部实现机制是很困难的,作为一名非底层程序员,我们只要能明白socket是一套操作系统封装好的函数,会创建能调用就OK了。在PHP里,要想创建一个socket是很轻松地事情。
例八:代码如下:
<?php
$host = "192.168.0.2";
$port = 12345;
set_time_limit(0);//最好在CLI模式下运行
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could notcreate socket\n");
// bind socket to port
$result = socket_bind($socket, $host, $port) or die("Could not bindto socket\n");
// start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socketlistener\n");
// accept incoming connections
// spawn another socket to handle communication
$spawn = socket_accept($socket) or die("Could not accept incomingconnection\n");
// read client input
$input = socket_read($spawn, 1024) or die("Could not readinput\n");
// clean up input string
$input = trim($input);
// reverse client input and send back
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could notwrite output\n");
// close sockets
socket_close($spawn);
socket_close($socket);
这   段代码的注释已经很详细了,如果你还想知道更多内情,可以访问http://www.devshed.com/c/a/PHP/Socket-Programming-With-PHP/,这个网站对socket的创建和使用进行来了很详细的讲解。由于PHP不支持多线程,只适合做客户端,而不适合做服务端,性能相对不高。所以一般服务端都是用C/JAVA等语言来实现,因此关于PHP创建socket服务端我就不做过多介绍了。(顺便提下:看到有人问PHP实现多线程的问题,有人一直坚称PHP可以实现多线程,甚至称自己已经写出一个多线程或者模拟出一个多线程了。其实很多人只是把多进程或者批量操作看做多线程,或者借助一些PHP的伙伴,linux操作系统或者web服务器来近似实现的。我想说的是,线程这玩意,不是某些人想得那么简单的。线程调度,线程间消息传递,休眠和唤醒,线程池,同步,锁,优先级等概念不是玩的,如果有人声称自己用php实现了多线程,那希望你能给我个完整的线程操作。或许,我会认为自己是孤陋寡闻。)
   另外,PHP的内存管理是非常非常糟糕的。由于它代替我们做了99%的内存管理,所以我们根本无法实现对内存的据需管理,而这在应用级服务上是致命的,所以PHP不能做应用及服务器端开发。即使它声称有防止内存泄露的机制,但实际上并非如此,也不要以为PHP就不存在野指针这类的问题。所以纠结于PHP多线程的PHP程序员都是蛋疼郎,除非你精通C,准备改造PHP源码。这个工作已经有人做了,不得不佩服这些TOP1%的PHP高手。剩下的99%就洗洗睡吧。以后,别在我面前提PHP的多线程及神马服务器开发。
   要在客户端操作socket,除了可以使用fsockopen函数外,还可以使用socket_create,stream_socket_client函数来实现。具体可以看手册。如果是php5的话,我建议使用stream_socket来实现socket操作。
原创粉丝点击