永发信息网

PHP和SOCKET和HTTP Connection: keep-alive疑惑 为什么

答案:2  悬赏:0  手机版
解决时间 2021-01-30 06:59
$fp = fsockopen("localhost", 80, $errno, $errstr, 3);
if (!$fp) {
echo "$errstr ($errno)
\n";
} else {
$out = "GET /upload.php HTTP/1.1\r\n";
$out .= "Host: localhost\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 1280);
}
fclose($fp);
}
为什么 Connection 要是Keep-Alive 相应速度奇慢 至少5秒 Close就是正常的速度 看我有很多构造头部的时候都不写这一项 不写一样会慢 难道客户端不主动断开连接就慢吗 这是为什么啊 求救
最佳答案
这个问题,你只要了解了 Keep-Alive 的用户,就不会迷惑了(详见HTTP协议)

Keep-Alive 的意义是保持客户端 <-> 的连接,这样在下次请求时就不必重建HTTP连接。

没有 Keep-Alive 的时候,一个请求可能0.1秒;

用了 Keep-Alive 之后,一个请求可能保持5秒,那么自然你感受到的就是“慢”
全部回答
在客户/服务器通信模式中,客户端需要主动建立与服务器连接的socket,服务器端收到客户端的连接请求,也会创建与客户端连接的socket。socket可以看做是通信连接两端的收发器,客户端和服务店都通过socket来收发数据。 1、构造socket public socket() 通过系统默认类型的 socketimpl 创建未连接套接字 public socket(string host,int port) throws unknownhostexception,ioexception 创建一个流套接字并将其连接到指定主机上的指定端口号。 public socket(string host,int port,inetaddress localaddr,int localport) throws ioexception 创建一个套接字并将其连接到指定远程主机上的指定远程端口。socket 会通过调用 bind() 函数来绑定提供的本地地址及端口。 public socket(inetaddress address,int port)throws ioexception创建一个流套接字并将其连接到指定 ip 地址的指定端口号。 public socket(inetaddress address,int port,inetaddress localaddr,int localport)throws ioexception创建一个套接字并将其连接到指定远程地址上的指定远程端口。socket 会通过调用 bind() 函数来绑定提供的本地地址及端口。 除第一个外,其他4个构造方法都会试图和服务器建立连接,如何连接成功则返回socket对象,如果连接失败就会抛出ioexception。 实例1:扫描主机上1到1024的端口,判断这些端口是否被服务器监听 [java] view plaincopy package com.hanfeng.socket; import java.io.ioexception; import java.net.socket; public class portscanner { public static void main(string[] args) { string host = "localhost"; if (args.length > 0) { host = args[0]; } new portscanner().scan(host); } public void scan(string host) { socket socket = null; for (int port = 1; port < 1024; port++) { try { socket = new socket(host, port); system.out.println("连接到端口:" + port); } catch (ioexception e) { system.out.println("无法连接到端口:" + port); } finally { try { if (socket != null) { socket.close(); } } catch (exception e) { e.printstacktrace(); } } } } } 1.1 设置等待连接超时时间 [java] view plaincopy public void scan(string host) { socket socket = null; socket = new socket(); socketaddress address = new inetsocketaddress(host, 1158); try { socket.connect(address, 60000); system.out.println("连接成功!"); } catch (ioexception e) { system.out.println("连接超时!"); e.printstacktrace(); } } 1.2设置服务器的ip地址 socket(inetaddress address, int port) //第一个参数address表示主机的ip地址 socket(string host, int port) //第一个参数host表示主机的名字 inetaddress类表示ip地址,其用法如下: //返回本地主机的ip地址 inetaddress addr1=inetaddress.getlocalhost(); //返回代表"222.34.5.7"的ip地址 inetaddress addr2=inetaddress.getbyname("222.34.5.7"); //返回域名为"www.google.com"的ip地址 inetaddress addr3=inetaddress.getbyname("www.google.com"); [java] view plaincopy public static void main(string[] args) { try { inetaddress address = inetaddress.getlocalhost(); system.out.println("本机ip地址:"+address); inetaddress address2 = inetaddress.getbyname("222.34.5.7"); system.out.println("返回远程ip地址:"+address2); inetaddress address3 = inetaddress.getbyname("www.google.com"); system.out.println("返回域名ip地址:"+address3); } catch (unknownhostexception e) { e.printstacktrace(); } } 1.3 设置客户端的ip地址 在一个socket对象中,既包含远程服务器的ip地址和端口信息,也包含本地客户端的ip地址和端口信息。默认情况下,客户端的ip地址来自于客户程序所在的主机,客户端的端口则由操作系统随机分配。socket类还有两个构造方法允许显式的设置客户端的ip地址和端口: socket(inetaddress address, int port, inetaddress localaddr, int localport)throws ioexception socket(string host, int port, inetaddress localaddr, int localport) throws ioexception 实例:一个主机在internet网络中的ip地址为”222.67.1.34“,在一个局域网中的ip地址为”112.5.4.3“。假定这个主机上的客户程序希望和同一个局域网上的一个服务器程序(112.5.4.45:8000)通信,则客户端可按照如下方式进行构造socket对象: [java] view plaincopy inetaddress remoteaddr = inetaddress.getbyname("112.5.4.45"); inetaddress localaddr = inetaddress.getbyname("112.5.4.3"); socket socket = new socket(remoteaddr,8000,localaddr,2345); 1.4客户端连接服务器可能抛出的异常 unknowhostexception:如果无法识别主机的名字或ip地址,就会抛出异常 connectexception:如果没有服务器进行监听指定的端口,或则服务器进程拒绝连接,就会抛出异常 sockettimeoutexception:等待连接超时,抛出异常 bindexcrption:如果无法把socket对象与具体的本地ip地址或端口绑定,就会抛出异常 以上4个异常都是ioexception的直接或间接子类,如下图 实例:捕获各种异常 [java] view plaincopy package com.hanfeng.socket; import java.io.ioexception; import java.net.bindexception; import java.net.connectexception; import java.net.inetsocketaddress; import java.net.socket; import java.net.socketaddress; import java.net.sockettimeoutexception; import java.net.unknownhostexception; public class connecttest { public static void main(string[] args) { string host = "www.google.com"; int port = 80; if (args.length>1) { host = args[0]; port = integer.parseint(args[1]); } new connecttest().connect(host, port); } public void connect(string host,int port){ socketaddress address = new inetsocketaddress(host, port); socket socket = null; string result = ""; try { long begin = system.currenttimemillis();//计算开始连接的时间 socket = new socket();//开始建立连接 socket.connect(address, 6000);//设置连接超时时间 long end = system.currenttimemillis();// 计算机连接结束的时间 result = (end-begin)+"ms"; } catch (bindexception e) { result = "ip地址或端口绑定异常!"; } catch (unknownhostexception e) { result = "未识别主机地址!"; }catch (sockettimeoutexception e) { result = "连接超时!"; }catch (connectexception e) { result = "拒绝连接!"; }catch (exception e) { result = "失败啦!"; }finally{ if (socket!=null) { try { socket.close(); } catch (ioexception e) { e.printstacktrace(); } } } system.out.println("远程地址信息==>"+address+":"+result); } } 2、获取socket信息 以下方法用于获取socket的有关信息: getinetaddress():获得远程服务器的ip地址。 getport():获得远程服务器的端口。 getlocaladdress():获得客户本地的ip地址。 getlocalport():获得客户本地的端口。 getinputstream():获得输入流。如果socket还没有连接,或者已经关闭,或者已经通过shutdowninput()方法关闭输入流,那么此方法会抛出ioexception。 getoutputstream():获得输出流。如果socket还没有连接,或者已经关闭,或者已经通过shutdownoutput()方法关闭输出流,那么此方法会抛出ioexception。 实例:httpclient类访问网页 [java] view plaincopy package com.hanfeng.socket; import java.io.bufferedreader; import java.io.bytearrayoutputstream; import java.io.inputstream; import java.io.inputstreamreader; import java.io.outputstream; import java.net.socket; public class httpclientdemo { string host ="www.google.com"; int port = 80; socket socket = null; public void createsocket() throws exception{ socket = new socket(host, port); } public void communicate() throws exception{ stringbuffer sb=new stringbuffer("get "+" http/1.1\r\n"); // sb.append("host: www.javathinker.org\r\n"); // sb.append("accept: * public static void main(string[] args) throws exception { httpclientdemo httpclient = new httpclientdemo(); httpclient.createsocket(); httpclient.communicate(); } } 3、关闭socket 当客户与服务器的通信结束,应该及时关闭socket,以释放socket占用的包括端口在内的各种资源。socket的close()方法负责关闭socket。当一个socket对象被关闭,就不能在通过他的输入流和输出流进行i/o操作,否则会导致ioexception。 为了确保关闭socket的操作总被执行,建议把这个操作放在finally代码块中。 [java] view plaincopy finally { try { if(socket!=null)socket.close(); } catch (ioexception e) { e.printstacktrace(); } } socket类提供了3个状态测试方法 isclosed():如果socket已经连接到远程主机,并且还没有关闭,则返回true isconnected():如果socket曾经连接到远程主机,则返回true isbound():如果socket已经与一个本地端口绑定,则返回true 如果要判断一个socket对象当前是否处于连接状态,可以采用以下方式: boolean isconnected = socket.isconnected()&&!socket.isclosed();
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
天剑群侠里面萧廷和唐若宣发生关系是哪一集?
我的充电器上写着输入100-240A~50/60Hz 0.2A
广利五金店地址在哪,我要去那里办事
我和我老公共同贷款购买的房屋现在银行债务还
魔域毛毯适合法师带吗
羁管的意思是什么啊?知道的请说下!
RGB转HSV,为什么opencv和matlab显示不一样
【一方砖多少块】一方砖是多少块
大转移后dnf剑宗为什么被削
人死了,男方娘家人指的是谁
HUAWEIP10#华为图库怎么设置才能不和云图库同
拜谢的意思是什么啊?知道的请说下!
轻卡货车哪个好
三星s7手机管家里的安全防护怎么拦截
支付宝别人发红包给我为什么都转入余额宝,怎
推荐资讯
京东购物,想申请售后,可订单列表已没有该商
ip1180进维修模式进不去,是因为只装黑墨盒而
禅茶一味地址在什么地方,想过去办事
炸完的带鱼身上有红色的斑点
鑫华快捷宾馆(焦作温县)地址在什么地方,我要
广州市环路159号是广州火车站吗
小二,来份后悔药的情侣网名
小狗便便有点绿有点软还吐了没精神
冬葱的意思是什么啊?知道的请说下!
鼻子大的女生应该要怎样化妆
我觉得,我碰到坏人了
今年扬州退休教师涨多少工资
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?