Python办事器开辟二:Python收集根蒂根基

    添加时间:2013-5-22 点击量:

    收集由下往上分为物理层、数据链路层、收集层、传输层、会话层、默示层和应用层。


    HTTP是高层和谈,而TCP/IP是个和谈集,很多的子和谈。包含:传输层的 FTP,UDP,TCP和谈等,收集层的ip和谈等,高层和谈如HTTP,telnet和谈等,HTTP是TCP/IP的一个子和谈。


    socket是对TCP/IP和谈的封装和应用(法度员层面上)。也可以说,TPC/IP和谈是传输层和谈,首要解决数据如安在收集中传输,而HTTP是应用层和谈,首要解决如何包装数据。


    我们在传输数据时,可以只应用(传输层)TCP/IP和谈,然则那样的话,若是没有应用层,便无法辨认数据内容,若是想要使传输的数占领意义,则必须应用到应用层和谈,应用层和谈有很多,比如HTTP、FTP、TELNET等,也可以本身定义应用层和谈。WEB应用HTTP和谈作应用层和谈,以封装HTTP文本信息,然后应用TCP/IP做传输层和谈将它发到收集上。


    而我们日常平凡说的最多的socket是什么呢,实际上socket是对TCP/IP和谈的封装,Socket本身并不是和谈,而是一个调用接口(API),经由过程Socket,我们才干应用TCP/IP和谈。实际上,Socket跟TCP/IP和谈没有必定的接洽。Socket编程接口在设计的时辰,就也能适应其他的收集和谈。所以说,Socket的呈现只是使得法度员更便利地应用TCP/IP和谈栈罢了,是对TCP/IP和谈的抽象,从而形成了我们知道的一些最根蒂根基的函数接口,比如create、listen、connect、accept、send、read和write等等。


    TCP/IP只是一个和谈栈,就像操纵体系的运行机制一样,必必要具体实现,同时还要供给对外的操纵接口。这个就像操纵体系会供给标准的编程接口,比如win32编程接口一样,TCP/IP也要供给可供法度员做收集开辟所用的接口,这就是Socket编程接口。


    有个斗劲形象的描述:HTTP是轿车,供给了封装或者显示数据的具体情势;Socket是发动机,供给了收集通信的才能。


     实际上,传输层的TCP是基于收集层的IP和谈的,而应用层的HTTP和谈又是基于传输层的TCP和谈的,而Socket本身不算是和谈,就像上方所说,它只是供给了一个针对TCP或者UDP编程的接口。


     


    哄骗Socket建树收集连接的步调:


    建树Socket连接至少须要一对套接字,此中一个运行于客户端,称为ClientSocket ,另一个运行于办事器端,称为ServerSocket 。


    套接字之间的连接过程分为三个步调:办事器,客户端恳求,连接确认。


    1。办事器:办事器端套接字并不定位具体的客户端套接字,而是处于守候连接的状况,及时监控收集状况,守候客户端的连接恳求。


    2。客户端恳求:指客户端的套接字提出连接恳求,要连接的目标是办事器端的套接字。为此,客户端的套接字必须起首描述它要连接的办事器的套接字,指出办事器端套接字的地址和端标语,然后就向办事器端套接字提出连接恳求。


    3。连接确认:当办事器端套接字到或者说接管到客户端套接字的连接恳求时,就响应客户端套接字的恳求,建树一个新的线程,把办事器端套接字的描述发给客户端,一旦客户端确认了此描述,两边就正式建树连接。而办事器端套接字持续处于状况,持续接管其他客户端套接字的连接恳求。



    HTTP链接的特点


    HTTP和谈即超文本传送和谈(Hypertext Transfer Protocol ),是Web联网的根蒂根基,也是联网常用的和谈之一,HTTP和谈是建树在TCP和谈之上的一种应用。


    HTTP连接最明显的特点是客户端发送的每次恳求都须要办事器回送响应,在恳求停止后,会主动开释连接。从建树连接到封闭连接的过程称为“一次连接”。




    The Internet Protocol(和谈)


    IP就是一个32位无符号整数。IP地址经由过程DNS (Domain Name System) 数据库映射到域名



    #!/usr/bin/env python
    
    # Foundations of Python Network Programming
    - Chapter 1 - getname.py
    import socket
    hostname
    = google.com
    addr
    = socket.gethostbyname(hostname)
    print
    The address of, hostname, is, addr
    # The address of google.com is 173.194.72.113




    Python收集编程:
    Python供给了接见底层操纵体系Socket接口的全部办法,还供给了一组加密和认证通信的办事,SSL/TLS。


    Sockets其实是一个文件描述符,不合于不合于本地文件,它连接了收集上的一个文件。


    1、创建一个UDP 本地连接:



    !/usr/bin/env python
    
    import socket, sys

    s
    = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    MAX
    = 65535
    PORT
    = 1060
    if sys.argv[1:] == [server]:
    s.bind((
    127.0.0.1, PORT))
    print Listening at, s.getsockname()
    while True:
    data, address
    = s.recv(MAX)
    print The client at, address, says, repr(data)
         s.sendto(Your data was %d bytes len(data), address)

    elif sys.argv[1:] == [client]:
    print Address before sending:, s.getsockname()
    s.sendto(
    This is my message, (127.0.0.1, PORT))
    print Address after sending, s.getsockname()
    data, address
    = s.recv(MAX) overly promiscuous - see text!
    print The server, address, says, repr(data)

    else:
    print >>sys.stderr, usage: udp_local.py server|client


    运行这段代码:



    python filename.py server
    
    #Listening at (
    127.0.0.1, 1060
    #Address before sending: (
    0.0.0.0, 0)
    #Address after sending (
    0.0.0.0, 62892
    #The server (
    127.0.0.1, 1060) says Your data was 18 bytes

    python filename.py client
    #The client at (
    127.0.0.1, 62892) says This is my message


    2、创建长途连接并验证收到的信息:



    import random, socket, sys
    
    s
    = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    MAX
    = 65535
    PORT
    = 1060

    if 2 <= len(sys.argv) <= 3 and sys.argv[1] == server:
    interface
    = sys.argv[2] if len(sys.argv) > 2 else
    s.bind((interface, PORT))
    print Listening at, s.getsockname()
    while True:
    data, address
    = s.recv(MAX)
    if random.randint(0, 1):
    print The client at, address, says:, repr(data)
    s.sendto(
    Your data was %d bytes len(data), address)
    else:
    print Pretending to drop packet , address

    elif len(sys.argv) == 3 and sys.argv[1] == client:
    hostname
    = sys.argv[2]
    s.connect((hostname, PORT))
    print Client socket name is, s.getsockname()
    delay
    = 0.1
    while True:
    s.send(
    This is another message
    print Waiting up to, delay, seconds for a reply
    s.settimeout(delay)
    try:
    data
    = s.recv(MAX)
    except socket.timeout:
    delay
    = 2 wait even longer for the next request
    if delay > 2.0:
    raise RuntimeError(I think the server is down
    else:
    break we are done, and can stop looping

    print The server says, repr(data)

    else:
    print >>sys.stderr, usage: udp_remote.py server [ <interface> ]
    print >>sys.stderr, or: udp_remote.py client <host>
    sys.exit(
    2)


    这里的s.connect((hostname, PORT))办法,可以让我们不消每次都调用s.sendto(This is my message, (127.0.0.1, PORT))。直接调用


    s.send(This is another message)。



    我们永远不要期待别人的拯救,只有自己才能升华自己。自己已准备好了多少容量,方能吸引对等的人与我们相遇,否则再美好的人出现、再动人的事情降临身边,我们也没有能量去理解与珍惜,终将擦肩而过。—— 姚谦《品味》
    分享到: