zoukankan      html  css  js  c++  java
  • python基础之socket

    1、TCP sorcket:

    server side(服务器端):

     1 import SocketServer
     2 class MyTCPHandler(SocketServer.BaseRequestHandler):
     3     def handle(self):
     4         self.data=self.request.recv(1024).strip()
     5         print "{} wrote".format(self.client_address[0])
     6         print self.data
     7         self.request.sendall(self.data.upper())
     8 if __name__=="__main__":
     9     HOST,PORT="localhost",9999
    10     server=SocketServer.TCPServer((HOST,PORT),MyTCPHandler)
    11     server.serve_forever()    

    解释:

    第1句引进相关模块;
    第2句定义类MyTCPHandler,它是继承自SocketServer的BaseRequestHandler类,该类还有相关的子类,下面会用到;
    第3句重写基类的handle()方法,有很多属性可以直接用,比如self.request,请求,self.request.recv(1024).strip()的意思是从客户端的请求那得到最大1kb的数据,并且数据.strip(),去掉前后的空格,中间的不会去掉的;
    self.client_adress是客户端的地址;
    第7句是把得到的数据转换成大写发给客户端;
    第8句是只有在直接运行当前程序是才会运行到的;
    HOST、PORT是主机地址和端口号;
    第10句就是创建一个server对象,是基于TCPServer类创建的;
    11句是启动服务监听的意思;

    上面是一种创建TCP server的方法,下面还有一种基于BaseRequestHandler基类StreamRequestHandler,当然它还有一个基类DatagramRequestHandler,两者有区别。

     1 import SocketServer
     2 class MyTCPHandler(SocketServer.StreamRequestHandler):
     3     def handle(self):
     4         self.data=self.rfile.readline().strip()
     5         print "{} wrote".format(self.client_address[0])
     6         print self.data
     7         self.wfile.write(self.data.upper())
     8 if __name__=="__main__":
     9     HOST,PORT="localhost",9999
    10     server=SocketServer.TCPServer((HOST,PORT),MyTCPHandler)
    11     server.serve_forever()

    基本上与上面的相同,但是毕竟StreamRequestHandler是BaseRequestHandler的基类,所以有一些新的方法。

    第4行,self.rfile.readline(), self.rfile类型是socket._fileobject,读写模式是"rb",方法有:read,readline,readlines,write(data),writelines(list),close,flush
    readline()方法会多次调用recv()方法,直到读取一行;其它的基本类似。

    the client side(客户端)

     1 import socket
     2 import sys
     3 HOST,PORT="localhost",9999
     4 data=" ".join(sys.argv[1:])
     5 sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     6 try:
     7     sock.connect((HOST,PORT))
     8     sock.sendall(data+"
    ")
     9     received=sock.recv(1024)
    10 finally:
    11     sock.close()
    12 print "Sent:  {}".format(data)
    13 print "Received:  {}".format(received)
    14 input()

    重点:建立一个socket对象sock,socket.SOCK_STREAM说明建立的是一个TCP socket,用socket.SOCK_DGRAM是UDP socket。

    sock.connect()方法是与主机建立连接,可见tcp协议是面向连接的可靠地通信协议,这正是tcp与udp协议的不同,udp协议是非面向连接的不可靠的协议,udp发送数据之前并不会与对方建立连接,而是直接发给对方。UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。
    比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。例如,在默认状态下,一次“ping”操作发送4个数据包。大家可以看到,发送的数据包数量是4包,收到的也是4包(因为对方主机收到后会发回一个确认收到的数据包)。这充分说明了UDP协议是面向非连接的协议,没有建立连接的过程。正因为UDP协议没有连接的过程,所以它的通信效率高;但也正因为如此,它的可靠性不如TCP协议高。
    QQ就使用UDP发消息,因此有时会出现收不到消息的情况。

    下面我们就用python来实现UDP的通信协议。

    udp服务器端:

     1 import SocketServer
     2 class MyUDPHandler(SocketServer.BaseRequestHandler):
     3     def handle(self):
     4         data=self.request[0].strip()
     5         socket=self.request[1]
     6         print "{} wrote".format(self.client_address[0])
     7         print data
     8         socket.sendto(data.upper(),self.client_address)
     9 if __name__=="__main__":
    10     HOST,PORT="localhost",9999
    11     server =SocketServer.UDPServer((HOST,PORT),MyUDPHandler)
    12     server.serve_forever()

    解释:udp的server与tcp的有一定的区别,它的self.request含有一个data和一个socket,分别用self.request[0]和self.request[1]获取,由于udp是面向非连接的协议,所以要用sendto()方法,并且要加上客户端的地址。

    udp客户端:

    1 import socket
    2 import sys
    3 HOST,PORT="localhost",9999
    4 data=" ".join(sys.argv[1:])
    5 sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    6 sock.sendto(data+"
    ",(HOST,PORT))
    7 received=sock.recv(1024)
    8 print "Sent:  {}".format(data)
    9 print "Received:  {}".format(received)

    可以看出与tcp的客户端相比,udp的sock并没有连接过程,直接发送的数据。

    运行,点击运行服务器端.py的文件,然后在命令行下:python d:/py/client.py hello world  (根据自己的文件地址写命令)回车就ok了,可以看到客户端服务器端都有输出数据。

  • 相关阅读:
    第三次作业
    第二次作业
    第一次作业
    第五次作业
    第四次作业
    第三次作业
    刘存俊第二次作业
    数据压缩第一次作业
    第五次作业
    第四次作业
  • 原文地址:https://www.cnblogs.com/nannanITeye/p/3271393.html
Copyright © 2011-2022 走看看