永发信息网

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

答案:2  悬赏:0  手机版
解决时间 2021-01-30 06:59
  • 提问者网友:原来太熟悉了会陌生
  • 2021-01-29 21:16
$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就是正常的速度 看我有很多构造头部的时候都不写这一项 不写一样会慢 难道客户端不主动断开连接就慢吗 这是为什么啊 求救
最佳答案
  • 五星知识达人网友:七十二街
  • 2021-01-29 22:53
这个问题,你只要了解了 Keep-Alive 的用户,就不会迷惑了(详见HTTP协议)

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

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

用了 Keep-Alive 之后,一个请求可能保持5秒,那么自然你感受到的就是“慢”
全部回答
  • 1楼网友:你可爱的野爹
  • 2021-01-29 23:51
在客户/服务器通信模式中,客户端需要主动建立与服务器连接的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();
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯