Python基础之(Socket编程)

一、什么是Socket

Socket又称为套接字,它是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

UNIX BSD发明了socket这种东西,socket屏蔽了各个协议的通信细节,使得程序员无需关注协议本身,直接使用socket提供的接口来进行互联的不同主机间的进程的通信。这就好比操作系统给我们提供了使用底层硬件功能的系统调用,通过系统调用我们可以方便的使用磁盘、内存,而无需自己去进行磁盘读写,内存管理。socket其实也是一样的东西,就是提供了tcp/ip协议的抽象,对外提供了一套接口,通过这个接口就可以统一、方便的使用tcp/ip协议的功能了。从使用上面看,socket就是一个模块。我们通过调用模块中已经实现的方法建立两个进程之间的连接和通信。也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。 所以我们只要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信。

二、套接字发展及分类

套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

基于网络类型的套接字家族

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

三、套接字的工作流程(基于TCP和 UDP两个协议)

3.1、TCP与UDP

TCP(Transmission Control Protocol)可靠的、面向连接的协议。传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;文件传输程序。

UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小)。一对一、一对多、多对一、多对多、面向报文(数据包),尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)

3.2、TCP协议下的Socket

先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

socket()模块函数用法:

import socket
socket.socket(socket_family,socket_type,protocal=0)
#socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。

#获取tcp/ip套接字
TcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#获取udp/ip套接字
UdpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#也可以‘from module import *‘语句,TcpSock = socket(AF_INET, SOCK_STREAM)

#服务端
s.bind()    绑定(主机,端口号)到套接字
s.listen()  开始TCP监听
s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来

#客户端
s.connect()     主动初始化TCP服务器连接
s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

#公共用途
s.recv()            接收TCP数据
s.send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom()        接收UDP数据
s.sendto()          发送UDP数据
s.getpeername()     连接到当前套接字的远端的地址
s.getsockname()     当前套接字的地址
s.getsockopt()      返回指定套接字的参数
s.setsockopt()      设置指定套接字的参数
s.close()           关闭套接字

3.2.1、TCP socket示例三连

简单一次发送接收版:

#最简单版

#server端
import socket
tcpserver = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #建立
tcpserver.bind(("127.0.0.1",10000))   #绑定
tcpserver.listen(5)  #监听
conn,addr = tcpserver.accept()  #阻塞等待连接
data = conn.recv(1024)   #接收
print(data.decode("utf-8"))
conn.send(data.upper())  #发送
conn.close()   #关闭连接
tcpserver.close()  #关闭

#client端
import socket
tcpclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpclient.connect(("127.0.0.1",10000))  #连接
data=input(">:")
tcpclient.send(data.encode("utf-8"))  #发送
ret=tcpclient.recv(1024)   #接收
print(ret.decode("utf-8"))
tcpclient.close()

执行结果:

循环接收发送信息示例:

#循环接收发送信息版

#server端
import socket
tcpserver = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpserver.bind(("127.0.0.1", 10000))
tcpserver.listen(5)
while True:
    conn,addr = tcpserver.accept()
    print(conn)
    while True:
        try:
            data = conn.recv(1024)
            print(data.decode("utf-8"))
            conn.send(data.upper())
        except Exception:
            break
    conn.close()
tcpserver.close()

#客户端
import socket
tcpclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpclient.connect(("127.0.0.1",10000))
while 1:
    while 1:
        data = input(‘>>>‘).strip()
        tcpclient.send(data.encode(‘utf-8‘))

        ret = tcpclient.recv(1024)

        print(ret.decode(‘utf-8‘))

执行结果:

远程执行结果返回示例:

(ret.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码,且只能从管道里读一次结果)

#server端
import socket
import subprocess
tcpserver = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpserver.bind(("127.0.0.1", 10000))
tcpserver.listen(5)
while True:
    conn,addr = tcpserver.accept()
    print(conn)
    while True:
        try:
            data = conn.recv(1024)
            ret=subprocess.Popen(data.decode(‘utf-8‘),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            error = ret.stderr.read()
            if error:
                cmd_ret = error
            else:
                cmd_ret=ret.stdout.read()
            conn.send(cmd_ret)
        except Exception:
            break
    conn.close()
tcpserver.close()

#客户端
import socket
tcpclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpclient.connect(("127.0.0.1",10000))
while 1:
    while 1:
        data = input(‘>>>‘).strip()
        tcpclient.send(data.encode(‘utf-8‘))

        ret = tcpclient.recv(1024)

        print(ret.decode(‘gbk‘))

执行结果:

3.3、UDP协议下的 Socket

UDP下的socket通讯流程:先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),recvform接收消息,这个消息有两项,消息内容和对方客户端的地址,然后回复消息时也要带着你收到的这个客户端的地址,发送回去,最后关闭连接,一次交互就结束了

3.3.1、Udp socket 示例二连

循环发送接收消息版:

#server端
import socket
ip_port=(‘127.0.0.1‘,10001)
udp_server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_server.bind(ip_port)
while True:
    msg,addr=udp_server.recvfrom(1024)
    print(msg,addr)
    udp_server.sendto(msg.upper(),addr)
udp_server.close()

#客户端
import socket
ip_port=(‘127.0.0.1‘,10001)
udp_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg=input(‘>>: ‘).strip()
    udp_client.sendto(msg.encode(‘utf-8‘),ip_port)
    msg,addr=udp_client.recvfrom(1024)
    print(msg.decode(‘utf-8‘),addr)
udp_client.close()

发送接收时间示例:

#server端:
import socket,time
ip_port=(‘127.0.0.1‘,10001)
udp_server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_server.bind(ip_port)
while True:
    msg,addr=udp_server.recvfrom(1024)
    if not msg:
        ret = "%Y-%m-%d %X"
    else:
        ret=msg.decode("utf-8")
    cmd_ret = time.strftime(ret)
    udp_server.sendto(cmd_ret.encode("utf-8"),addr)
udp_server.close()

#客户端:
import socket
ip_port=(‘127.0.0.1‘,10001)
udp_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg=input(‘>>: ‘).strip()
    udp_client.sendto(msg.encode(‘utf-8‘),ip_port)

    msg,addr=udp_client.recvfrom(1024)
    print(msg.decode(‘utf-8‘))

执行结果:

注意点:

  • udp是无链接的,先启动哪一端都不会报错,而tcp需要先启动server端
  • 由于udp无连接,所以可以同时多个客户端去跟服务端通信,而tcp同时只能有一个客户端与服务端连接,其他客户端只能等待中,直到连接中客户端下线

四、粘包

4.1、Socket 缓冲区

  每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。read()/recv() 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取

4.2、粘包的原因

TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。

UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。

udp的recvfrom是阻塞的,一个recvfrom(x)必须对唯一一个sendinto(y),收完了x个字节的数据就算完成,若是y>x数据就丢失,这意味着udp根本不会粘包,但是会丢数据,不可靠。tcp的协议数据不会丢,没有收完包,下次接收,会继续上次继续接收,己端总是在收到ack时才会清除缓冲区内容。数据是可靠的,但是会粘包。

所以所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。并且只有TCP有粘包现象,UDP永远不会粘包!

粘包的两种情况:

  • 接收方没有及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)
  • 发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据也很小,会合到一起,产生粘包)

4.3、解决粘包的方法

粘包问题的根源在于接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是如何让发送端在发送数据前先把自己将要发送的数据大小让接收端知晓,然后再来一个循环接收完所有数据

#服务端
import socket,subprocess
ip_port=(‘127.0.0.1‘,10001)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(ip_port)
s.listen(5)

while True:
    conn,addr=s.accept()
    while True:
        try:
            msg=conn.recv(1024)
            res=subprocess.Popen(msg.decode(‘utf-8‘),shell=True,stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
            error=res.stderr.read()
            if error:
                ret=error
            else:
                ret=res.stdout.read()
            data_length=len(ret)
            print(data_length)
            conn.send(str(data_length).encode(‘utf-8‘)) #发送长度
            data=conn.recv(1024).decode(‘utf-8‘)
            if data == ‘ready‘:    #确认
                conn.sendall(ret)   #发送全部数据
        except Exception:
            break
    conn.close()
s.close()

#客户端
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((‘127.0.0.1‘,10001))
while True:
    msg=input(‘>>: ‘).strip()
    s.send(msg.encode(‘utf-8‘))
    length=int(s.recv(1024).decode(‘utf-8‘))   #接收长度
    print(length)
    s.send(‘ready‘.encode(‘utf-8‘))
    recv_size=0
    data = b""
    while recv_size < length:   #如果长度不够就一直接收,直到完成
        r_m = s.recv(1024)
        data+= r_m
        recv_size+=len(r_m)
    print(recv_size)
    print(data.decode(‘gbk‘))

另一种解决粘包的方法即是:将总数据大小封装成固定大小后和数据分别发,接收方先接收封装的总数据大小,然后再接收数据

五、SocketServer 实现并发

基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环。而socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)

#server 端
import socketserver
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request)
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print(self.data)
                self.request.sendall(self.data.upper())
            except Exception:
                break

if __name__ == "__main__":
    HOST, PORT = "127.0.0.1", 10001
    # 创建一个server, 将服务地址绑定到127.0.0.1:10001 (TCP socket)
    # server = socketserver.TCPServer((HOST, PORT),Myserver)
    #(多线程)
    server = socketserver.ThreadingTCPServer((HOST, PORT), Myserver)
     #(多进程)
    #server=socketserver.ForkingTCPServer((host,port),myserver)
    # 让server永远运行下去,除非强制停止程序
    server.serve_forever()

#客户端
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((‘127.0.0.1‘,10001))
while True:
    msg=input(‘>>: ‘).strip()
    s.send(msg.encode(‘utf-8‘))
    data=s.recv(1024)
    print(data.decode(‘utf-8‘))

执行结果:

补充udp 并发:

#udp  socketserver
import socketserver
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request)
        self.data = self.request[0]
        print(self.data)
        self.request[1].sendto(self.request[0].upper(), self.client_address)
if __name__ == "__main__":
    HOST, PORT = "127.0.0.1", 10001
    # server = socketserver.TCPServer((HOST, PORT),Myserver)
    server = socketserver.ThreadingUDPServer((HOST, PORT), Myserver)
    # 让server永远运行下去,除非强制停止程序
    server.serve_forever()

#客户端
import socket
ip_port=(‘127.0.0.1‘,10001)
udp_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg=input(‘>>: ‘).strip()
    udp_client.sendto(msg.encode(‘utf-8‘),ip_port)
    msg,addr=udp_client.recvfrom(1024)
    print(msg.decode(‘utf-8‘),addr)
udp_client.close()

基于tcp的socketserver我们自己定义的类中的

  • self.server即套接字对象
  • self.request即一个链接  (self.request  = conn)
  • self.client_address即客户端地址

基于udp的socketserver我们自己定义的类中的

  • self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),如(b‘adsf‘, <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=(‘127.0.0.1‘, 8080)>)
  • self.client_address即客户端地址

六、客户端连接合法示例

#server端
import socketserver
import hmac,os
secret_key=b‘Crazyjump‘
def conn_auth(conn):
    ‘‘‘
    认证客户端链接
    ‘‘‘
    print(‘开始验证新链接的合法性‘)
    msg=os.urandom(16) #随机生成16个字节的串
    print(msg)
    conn.sendall(msg)
    h=hmac.new(secret_key,msg)
    digest=h.digest()
    respone=conn.recv(len(digest))
    return hmac.compare_digest(respone,digest)

def data_handler(conn,bufsize=1024):
    if not conn_auth(conn):
        print(‘该链接不合法,关闭‘)
        conn.close()
        return
    print(‘链接合法,开始通信‘)
    while True:
        try:
            data=conn.recv(bufsize)
            conn.sendall(data.upper())
        except Exception:
            break
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        data_handler(self.request)
if __name__ == "__main__":
    HOST, PORT = "127.0.0.1", 10001
    server = socketserver.ThreadingTCPServer((HOST, PORT), Myserver)
    server.serve_forever()
#(单)
#def server_handler(ip_port,bufsize,backlog=5):
    ‘‘‘
    只处理链接
    ‘‘‘
   # tcp_socket_server=socket(AF_INET,SOCK_STREAM)
    #tcp_socket_server.bind(ip_port)
   # tcp_socket_server.listen(backlog)
    #while True:
       # conn,addr=tcp_socket_server.accept()
        #print(‘新连接[%s:%s]‘ %(addr[0],addr[1]))
        #data_handler(conn,bufsize)

#客户端
from socket import *
import hmac,os

secret_key=b‘Crazyjump‘
def conn_auth(conn):
    ‘‘‘
    验证客户端到服务器的链接
    ‘‘‘
    msg=conn.recv(16)
    h=hmac.new(secret_key,msg)
    digest=h.digest()
    conn.sendall(digest)

def client_handler(ip_port,bufsize=1024):
    tcp_socket_client=socket(AF_INET,SOCK_STREAM)
    tcp_socket_client.connect(ip_port)
    conn_auth(tcp_socket_client)

    while True:
        data=input(‘>>: ‘).strip()
        if not data:continue
        if data == ‘quit‘:break

        tcp_socket_client.sendall(data.encode(‘utf-8‘))
        respone=tcp_socket_client.recv(bufsize)
        print(respone.decode(‘utf-8‘))
    tcp_socket_client.close()

if __name__ == ‘__main__‘:
    ip_port=(‘127.0.0.1‘,10001)
    bufsize=1024
    client_handler(ip_port,bufsize)

  

  

原文地址:https://www.cnblogs.com/crazyjump/p/10210373.html

时间: 2024-10-12 16:41:12

Python基础之(Socket编程)的相关文章

python基础之socket编程

python基础之socket编程   一 TCP/IP五层模型 在每一层都工作着不同的设备,比如我们常用的交换机就工作在数据链路层的,一般的路由器是工作在网络层的. 在每一层实现的协议也各不同,即每一层的服务也不同.下图列出了每层主要的协议. 各层功能 注明:ARP和RAPR两个到底属于哪一层呢? 由于IP协议使用了ARP协议,所以经常把ARP协议划到网络层,但是ARP协议是为了从网络层使用的IP地址解析出在数据链路层使用的MAC地址,所以有些地方也把ARP协议划分到数据链路层,但是一般情况下

Python 基础之socket编程(二)

Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 1. tcp的服务端 ss = socket() #创建服务器套接字 ss.bind() #把地址绑定到套接字 ss.listen() #监听链接 inf_loop: #服务器无限循环 cs = ss.accept() #接受客户端链接 comm_loop: #通讯循环 cs.recv()/cs.

Python 基础之socket编程(三)

python 基础之socket编程(三) 前面实现的基于socket通信只能实现什么呢?在tcp协议的通信中就是一个用户说一句,服务端给你回一句,你再给服务端说一句,服务端再给你回一句,就这样一直友好的玩耍下去了.等等,又有一个用户来了,他呢也想和和服务端进行一下交流,于是他就给服务端发送了一条消息,之后等呀等不知过了多久,任然没有等到服务端给他发挥的消息,只有什么时候他就可以和服务端愉快的玩耍了呢?这个就需要第一个用户退出和服务器的链接,此时第二个客户端才会和服务端建立起链接,此时此刻,他才

python基础之socket编程 (转自林海峰老师)

阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 粘包现象 十 什么是粘包 十一 解决粘包的low比处理方法 十二 峰哥解决粘包的方法 十三 认证客户端的链接合法性 十四 socketserver实现并发 十五 作业 一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B

python基础20 ------python基础之socket编程

一.C/S架构和B/S架构的简介 略 二.osi七层模型 略 三.socket层 1.如图所示: socket层是存在于应用层和传输层直接抽象出来的一层. 2.socket层是什么? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的 TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议.所以,我们无需 深入理解tcp/udp协议,socke

python基础之socket编程-------基于tcp的套接字实现远程执行命令的操作

远程实现cmd功能: import socket import subprocess phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(("127.0.0.1",8080)) phone.listen(5) print("starting....") while True: conn,addr=phone.accept() while True: try: date=conn.recv

python基础之socket编程(TCP三次握手和四次挥手)

TCP协议中中的三次握手和四次挥手 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了. 那如何断开连接呢?简单的过程如下: [注意]中断连接端可以是Client端,也可以是Server端. 假设Client端发起中断连接请求,也就是发送FIN报

python基础之socket编程part2---粘包和并发

粘包现象 基于tcp的套接字实现远程执行命令的操作(1.执行错误命令.2.执行ls.3.执行ipconfig) #_*_coding:utf-8_*_ __author__ = '777' import socket import subprocess phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(("127.0.0.1",8080)) phone.listen(5) print("等待命令

Python学习记录-socket编程

Python学习记录-socket编程 学习 python socket Python学习记录-socket编程 1. OSI七层模型详解 2. Python socket 3. socket()函数 4. TCP socket通信流程 5. Python Internet 模块 1. OSI七层模型详解 以上图见:http://blog.csdn.net/yaopeng_2005/article/details/7064869 其它详情可参考:socket网络基础 2. Python sock

Day6 - Python基础6 面向对象编程

Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11