zoukankan      html  css  js  c++  java
  • python——初识socket

    什么是socket  

      网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

      Socket的英文原义是“孔”或“插座”。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。

      我知道上面那段话很枯燥,那就忘记吧!我们只需要记得:两个程序通过“网络”交互数据就使用socket,它只负责两件事:建立连接,传递数据。不能再简练了!!!

    如何执行一段socket代码?

      首先,我们先看下面这个例子,什么都不需要懂,我们只知道这么写就可以实现一个socket,让两个程序互相传递消息:

      server:     client:                      

      先说一下它们是怎么跑起来的,新建两个python文件:socket_server.py,socket_client.py 分别将demo1_server Codedemo1_client Code中的代码粘到对应的文件中,先执行socket_server.py,再执行socket_client.py,就可以看到效果啦!代码拿去,先体验一下socket的效果。

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 __author__ = 'Eva_J'
     4 import socket
     5 
     6 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     7 sock.bind(('127.0.0.1',8001))
     8 sock.listen(5)
     9 
    10 while True:
    11     print 'waiting....'
    12     connection, address = sock.accept()
    13     receive = connection.recv(1024)
    14     print 'receive the message from client:',receive
    15     connection.send("received")
    16     connection.close()
    demo1_server Code
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 __author__ = 'Eva_J'
     4 import socket
     5 
     6 obj_client = socket.socket()
     7 obj_client.connect(('127.0.0.1',8001))
     8 obj_client.send('help')
     9 server_data = obj_client.recv(1024)
    10 print server_data
    11 obj_client.close()
    demo1_client Code

    一分钟拥有一个自己的socket程序!

      执行成功了么?我们先不解释原理,一切以能把socket用起来为前提,把上面这段代码当做实现socket的模板代码,来看看哪些东西是我们可以替换的,先拼凑一个属于自己的socket程序。

      server:        client:

                              

      我们先从打印出来的内容来看,server端接收到了从client端发送过来的信息 'help' 。并且给client端发送了一条确认信息 'received',我们在client端接收到了这条信息。这就是数据交互的过程。send是发消息方法,recv是接收消息方法。我们只需要修改send和recv中的内容,就可以实现两个程序的数据交互了。

      socket的实现就像是快递员取快递的过程,寄出包裹的是server端,快递员是client端,send和recv中的内容就是我们要寄出的东西,那么准备好了要寄出的东西,我们要告诉快递员到哪里来取件,看server中的sock.bind方法,这里面传了一个元组('ip','port')给bind方法,就是把包裹放在这个地址的这个端口等待快递员;而client端的obj_client.connect方法是告诉快递员,去那个地址找这个端口去取包裹。所以这个元组中的ip和port内容必须一致,是我和快递员约好的。我send的内容无所谓是什么,我send什么,客户端就recv什么,因为我要寄什么,快递员拿到的就是什么,他没有权利左右我寄什么东西。现在就行动起来,把要寄的东西和放东西的地址换成你自己的,来get一个属于自己的socket程序吧。

    socket程序代码详解:

       server:     client:

     创建socket对象——参数详解:

                                         

      参数一:地址簇

        socket.AF_INET IPv4(默认)
        socket.AF_INET6 IPv6

        socket.AF_UNIX 只能够用于单一的Unix系统进程间通信

      参数二:类型

        socket.SOCK_STREAM  流式socket , for TCP (默认)
        socket.SOCK_DGRAM   数据报式socket , for UDP

        socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利  用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
        socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
        socket.SOCK_SEQPACKET 可靠的连续数据包服务

      参数三:协议(这个参数用默认的就好,所以在我们创建对象的时候没有使用此参数,忘记这个参数吧)

        0  (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议'

    UDP协议实现socket代码实例:

      我们刚刚看的例子中都是使用TCP协议进行传输,下面上一段UDP的例子。

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 import socket
     4 ip_port = ('127.0.0.1',9999)
     5 
     6 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
     7 while True:
     8     inp = raw_input('数据:').strip()
     9     if inp == 'exit':
    10         break
    11     sk.sendto(inp,ip_port)
    12 sk.close()
    UDP Server Code
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    ip_port = ('127.0.0.1',9999)
    sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
    sk.bind(ip_port)
    
    while True:
        data = sk.recv(1024)
        print data
    UDP Client Code

    参考:

    socket详解:http://www.cnblogs.com/wupeiqi/articles/5040823.html

    TCP和UDP协议的区别:http://jingyan.baidu.com/article/6dad5075df3452a123e36ecb.html

  • 相关阅读:
    一天进步一点点
    Flask
    Sqlalchemy 设置表编码及引擎
    threading.local
    xshell配置密码公钥登录
    linux 系统优化+定时任务
    linux命令
    xshell连接及优化
    linux前奏
    Vue Devtools--vue调式工具
  • 原文地址:https://www.cnblogs.com/Eva-J/p/5045061.html
Copyright © 2011-2022 走看看