socket编程实例详解

2019-11-26 16:35 来源:未知

在fms4以前Adobe只允许在stratus中才能使用p2p功能。令人高兴的是,在最新发布的fms4中,p2p功能已经集成进来了,这将给实时视频类的应用带来更高的效率,adobe这次很给力!

一,1个HTTP请求一般由四部分组成:

1.HTTP请求的方法或动作,比如是GET还是POST
2.正在请求的URL,总得知道请求的地址是什么吧
3.请求头,包含一些客户端环境信息,身份验证信息等
4.请求体,也就是请求正文,请求正文中可以包含客户提交的查询字符串信息,    表单信息等

(1)GET请求:一般用于信息获取
a.使用URL传递参数
b.对所发送信息的数量也是有限制的,一般在2000个字符

(2)POST请求:一般用于修改服务器上的资源
a.对所发送信息的数量无限制
一个HTTP响应一般由三部分组成:
(1)一个数字和文字组成的状态码,用来显示请求是成功还是失败
(2)响应头,响应头也和请求头一样包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度等
(3)响应体,也就是响应正文

Python socket编程实例详解,python编程实例

本文实例形式较为详细的讲述了Python socket编程。分享给大家供大家参考。具体如下:

复制代码 代码如下:sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
上面的代码创建了一个socket对象。type参数代表套接字类型,可为SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字)。AF_INET表示创建的是ip v4的类型。
复制代码 代码如下:socket(address_family,type,protocol_type):

上面三个参数的含义是:

address_family指明要建立哪一类socket。最常用的当然是ip协议,AF_INET。在unix系统中,AF_UNIX也是比较常用的,用于建立unix系统中的进程间通信。

type用于指定通信类型。通常是建立面向连接的流通信。SOCKET_DGRAM是报文通信。如果address_family设置的是AF_INET,那么对应的是TCP和UDP。

protocol用于指定协议类型。这个参数是可选的。在建立tcp或者是udp连接的时候他们通常都是0。如果第一个参数是AF_INET,那么这个参数表示是ip包中的protocol字段。

【UDP本来就不区分server和client。所有节点都是对等的】

第二步是将socket绑定到指定的地址:
复制代码 代码如下:sock.bind(('localhost',7556))
第三步是使用listen方法监听请求:【listen方法中的参数指明可接受的最大连接数】
复制代码 代码如下:sock.listen(5)
第四步是不断接收请求:收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
复制代码 代码如下:connection,address = sock.accept()
accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
第五步是处理阶段,服务器和客户端通过send和recv方法通信(传输数据)。

如果send成功了,那么对方的缓冲区已经有你发送的数据了。
#调用recv 时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv方法在接收数据时会进入“blocked”状态,最后返回一个字符 串,用它表示收到的数据。如果发送的数据量超过了recv所允许的,数据会被截短。多余的数据将缓冲于接收端。以后调用recv时,多余的数据会从缓冲区 删除(以及自上次调用recv以来,客户可能发送的其它任何数据)。

connection.settimeout(5)
buf = connection.recv(1024)

具体处理如下:

      if buf == '1':
  connection.send('welcome to python server!')
else:
  connection.send('please go out!')

使用send发送数据给客户端。客户端使用recv来接收数据。

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost',7556))
import time
time.sleep(2)
sock.send('1')
print sock.recv(1024)
sock.close()

这就是整个通信过程了。

全部代码如下:

server端:

#!/usr/bin/env python
import socket
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(('localhost',7556))
sock.listen(5)
while True:
  connection,address = sock.accept()
  print "client ip is "
  print address
  try:
    connection.settimeout(5)
    buf = connection.recv(1024)
    if buf == '1':
      connection.send('welcome to python server!')
    else:
      connection.send('please go out!')
  except socket.timeout:
    print 'time out'
  connection.close()

client端如下:

#!/usr/bin/env python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost',7556))
import time
time.sleep(2)
sock.send('1')
print sock.recv(1024)
sock.close()

记住,socket使用完毕之后要关闭。【上面的代码,server端忘记关闭socket了】
当然,在socket连接的过程中,最好使用try except来做一下错误处理。

注意,accept函数和recv函数都是阻塞式的。也就是说,他们一直在等待,直到有客户端连接过来或者是后者的有数据可以接收。

下面是一个FTP的小例子。

使用了多线程来处理每一个请求。

示例代码点击此处本站下载。

如果传输路径不存在则建立。

希望本文所述对大家的Python程序设计有所帮助。

socket编程实例详解,python编程实例 本文实例形式较为详细的讲述了Python socket编程。分享给大家供大家参考。具体如下: 复制代码 代...

为了使用p2p,开发用的flex sdk至少要4.1以上(当然最高版本是代号为hero的4.5版本,可从adobe的官网下载),另外还需要fms4(同样可从adobe官网下载开发版本)。

二、XMLHttpRequest对象

1.首先,新建一个XMLHttpRequest的实例 :

   var xhr = new XMLHttpRequest();

2.然后,向远处主机发出一个HTTP请求:

    xhr.open('GET','example.php');
    xhr.send();

3.接着,等待远程主机做出回应。这时需要监控XMLHttpRequest对象的状态变化,指定回调函数:

xhr.onreadystatechange = function(){
    if(xhr.readyState == 4 && xhr.status == 200){
        alert(xhr.responseText);
    }else{
        alert(xhr.statusText);
    }
}

上面的代码包含了老版本XMLHttpRequest对象的主要属性;
xhr.readyState:XMLHttpRequest对象的状态
0:请求未初始化,open还没调用
1:服务器连接已建立,open已经调用了
2:请求已接收,也就是接收到头信息了
3:请求处理中,也就是接收到响应主体了
4:请求已完成,且响应已就绪,也就是响应完成了

xhr.status:服务器返回的状态码,等于200表示一切正常
responseText:获得字符串形式的数据
responseXML:获得XML形式的响应数据
status和statusText:以数字和文本形式返回HTTP状态码:

1信息类 表示收到web浏览器请求,正在进一步的处理中
2成功
3重定向
4客户端错误
5服务器错误

getAllResponseHeader():获取所有的响应报头
老版本的XMLHttpRequest对象的几个缺点:
1.只支持文本数据的传送,无法用来读取和上传二进制文件
2.传送和接收数据时,没有进度信息,只能提示有没有完成
3.受到“同域限制”,只能向同一域名的服务器请求数据
新版本的功能

  • 可以设置HTTP请求的时限
  • 可以使用FormData对象管理表单数据
  • 可以上传文件
  • 可以请求不同域名下的数据
  • 可以获取服务器端的二进制数据
  • 可以获得数据传输的进度信息

HTTP请求时限:

    xhr.timeout = 3000;

上面语句将等待时间设为3000毫秒。过了这个时限,就自动停止HTTP请求。
与之配套的还有一个timeout事件,用来指定回调函数

    xhr.timeout = function(event){
        alert('请求超时!');
    }

目前,Opera、Firefox和IE 10支持该属性,IE 8和IE 9的这个属性属于XDomainRequest对象,而Chrome和Safari还不支持。

先上完整代码吧:

三、FormData对象

ajax操作往往用来传递表单数据。为了方便表单处理,HTML 5新增了一个FormData对象,可以模拟表单。
首先,新建一个FormData对象。

  var formData = new FormData();

然后,为它添加表单项。

  formData.append('username', '张三');
  formData.append('id', 123456);

最后,直接传送这个FormData对象。这与提交网页表单的效果,完全一样。

xhr.send(formData);

FormData对象也可以用来获取网页表单的值:

var form = document.getElementById('myform');
var formData = new FormData(form);
formData.append('secret', '123456'); // 添加一个表单项
xhr.open('POST', form.action);
xhr.send(formData);
package {

    import fl.controls.Button;
    import fl.controls.Label;
    import fl.controls.TextArea;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.NetStatusEvent;
    import flash.net.GroupSpecifier;
    import flash.net.NetConnection;
    import flash.net.NetGroup;
    import flash.net.NetGroupReplicationStrategy;
    import flash.text.TextFormat;


    public class p2p_HelloWorld extends Sprite {

        private var _lbl:Label;
        private var _btnAddToWant:Button;
        private var _btnGenData:Button;
        private var _btnAddToHave:Button;
        private var _txtObj:TextArea;
        private var _txtOutput:TextArea;
        private var _data:Vector.<String>;
        private var _dataLength:uint = 100;
        private var _nc:NetConnection;
        private var _ng:NetGroup;
        private var _spec:GroupSpecifier;
        private var _server:String = "rtmfp://localhost/HelloServer";
        private var _groupName:String = "myGroup";
        private var _connected:Boolean = false;

        public function p2p_HelloWorld(){
            init();
        }

        private function init():void {
            this._btnAddToWant = btnAddToWant;
            this._btnAddToHave = btnAddToHave;
            this._btnGenData = btnGenData;
            this._txtObj = txtObj;
            this._txtOutput = txtOutput;
            this._lbl = lbl;

            var style:TextFormat = new TextFormat("宋体", 12, 0x000000,false,false,false,null,null,null,null,null,null,5);
            this._btnAddToHave.setStyle("textFormat", style);
            this._btnAddToWant.setStyle("textFormat", style);
            this._btnGenData.setStyle("textFormat", style);
            this._txtObj.setStyle("textFormat", style);
            this._txtOutput.setStyle("textFormat", style);
            this._lbl.setStyle("textFormat", style);

            this._btnGenData.addEventListener(MouseEvent.CLICK, _btnGenData_Click);
            this._btnAddToHave.addEventListener(MouseEvent.CLICK, _btnAddToHave_Click);
            this._btnAddToWant.addEventListener(MouseEvent.CLICK, _btnAddToWant_Click);

            //先连接到服务器
            _nc = new NetConnection();
            _nc.addEventListener(NetStatusEvent.NET_STATUS, _nc_Net_Status);
            _nc.connect(_server);
            output("正在连接 " + _server + " ...");
        }

        private function _nc_Net_Status(e:NetStatusEvent):void {
            output(e.info.code);
            switch (e.info.code){
                case "NetConnection.Connect.Success":   
                    //连接成功后,要设置NetGroup
                    this._spec = new GroupSpecifier(this._groupName);                   
                    _spec.serverChannelEnabled = true;//设置允许创建到服务端的通道
                    _spec.objectReplicationEnabled = true;//允许对象复制
                    _ng = new NetGroup(_nc, _spec.groupspecWithAuthorizations());
                    _ng.addEventListener(NetStatusEvent.NET_STATUS, _nc_Net_Status);
                    break;
                case "NetGroup.Connect.Success":
                    _connected = true;
                    _ng.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;//设置数据块传输时,先传递索引号最小的块
                    break;
                case "NetGroup.Replication.Fetch.SendNotify": 
                    //每当"接收方"有数据到达(但尚未开始接收)时,将触发此处理
                    output("    -->通知:数据块 " + e.info.index + "  即将被接收");
                    break;
                case "NetGroup.Replication.Fetch.Failed": 
                    //“接收方”有数据接收失败时,将触发此处理
                    output("    -->错误:数据块 " + e.info.index + " 接收失败");
                    break;
                case "NetGroup.Replication.Fetch.Result": 
                    //“接收方”每次成功接收到数据时,触发此段处理
                    output("    -->数据块 " + e.info.index + " 已成功接收,值:" + e.info.object);
                    _ng.addHaveObjects(e.info.index, e.info.index); //接收完成以后,将接收到的数据加入“待发送对象列表"中,这样人越多,传输越稳定,速度也越快  
                    if (_data == null) {
                        _data = new Vector.<String>(this._dataLength);
                    }
                    _data[e.info.index] = e.info.object.toString();
                    //说明全部接收完了
                    if (e.info.index == this._dataLength - 1) {
                        for (var i:int = 0; i < _dataLength; i++){
                            _data[i] = "这是数据 " + i.toString();
                            this._txtObj.appendText("index:" + i.toString() + ",data:" + _data[i] + " | ");
                        }
                    }
                    break;
                case "NetGroup.Replication.Request": 
                    //每当有数据传输请求时,“提供方”将触发此处理
                    _ng.writeRequestedObject(e.info.requestID, _data[e.info.index]);//这里才是真正的响应“接收方",将指定的数据发送过去
                    output("    -->数据块 " + e.info.index + " 请求被发送,本次请求ID:" + e.info.requestID);
                    break;
                default:
                    break;
            }
        }

        //初始化生成数据
        private function _btnGenData_Click(e:MouseEvent):void {
            this._txtObj.text = "";
            if (_data==null){
                _data = new Vector.<String>(this._dataLength);
            }
            for (var i:int = 0; i < _dataLength; i++){
                _data[i] = "这是数据 " + i.toString();
                this._txtObj.appendText("index:" + i.toString() + ",data:" + _data[i] + " | ");
            }
        }

        //将生成的初始数据,添加到待发送的“列表”中
        private function _btnAddToHave_Click(e:MouseEvent):void 
        {
            this._ng.addHaveObjects(0, _dataLength - 1);
        }

        //请求接收数据
        private function _btnAddToWant_Click(e:MouseEvent):void
        {
            this._ng.addWantObjects(0, _dataLength - 1);
        }

        //输出结果
        private function output(s:String):void {
            this._txtOutput.appendText(s + "n");
        }
    }

}

四、上传文件

新版XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件。
假定files是一个"选择文件"的表单元素(input[type="file"]),我们将它装入FormData对象。

  var formData = new FormData();
  for (var i = 0; i < files.length;i++) {
    formData.append('files[]', files[i]);
  }

然后,发送这个FormData对象。

  xhr.send(formData);

在这段代码中我们看到了一个全新的NetGroup对象,要使用p2p,“接收方”与“接收方”必须先加入到“相同名称"的NetGroup中。而且要发送的数据,必须分解有顺序的一块一块(通常用有序数组来保存这些数据块),然后"发送方"调用addHaveObjects方法设置待发送的数据块,而"接收方"则调用addWantObjects请求需要接收的块。

五、跨域资源共享(CORS)

新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称CORS)。
使用"跨域资源共享"的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种"跨域"。如果能够满足上面的条件,则代码的写法与不跨域的请求完全一样。

  xhr.open('GET', 'http://other.server/and/path/to/script');

目前,除了IE 8和IE 9,主流浏览器都支持CORS,IE 10也将支持这个功能。服务器端的设置,请参考《Server-Side Access Control》。

一旦"接收方"调用了addWantObjects方法后,"发送方"便会进入"NetGroup.Replication.Request"状态,此时"发送方"响应"接收方"的请求,将需要的数据块以udp协议发送过去,然后“接收方”会收到"NetGroup.Replication.Fetch.SendNotify"的数据到达通知,如果成功接收,将进入“NetGroup.Replication.Fetch.Result”状态,全部接收完成后,开发人员可根据需要将这些块重新合并成原始对象。

八、接收二进制数据(方法A:改写MIMEType)

老版本的XMLHttpRequest对象,只能从服务器取回文本数据(否则它的名字就不用XML起首了),新版则可以取回二进制数据。
这里又分成两种做法。较老的做法是改写数据的MIMEType,将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集。

  xhr.overrideMimeType("text/plain; charset=x-user-defined");

然后,用responseText属性接收服务器返回的二进制数据。

  var binStr = xhr.responseText;

由于这时,浏览器把它当做文本数据,所以还必须再一个个字节地还原成二进制数据。

  for (var i = 0, len = binStr.length; i < len; ++i) {
    var c = binStr.charCodeAt(i);
    var byte = c & 0xff;
  }

最后一行的位运算"c & 0xff",表示在每个字符的两个字节之中,只保留后一个字节,将前一个字节扔掉。原因是浏览器解读字符的时候,会把字符自动解读成Unicode的0xF700-0xF7ff区段。

TAG标签:
版权声明:本文由金沙澳门官网4166发布于世界史,转载请注明出处:socket编程实例详解