Python网络编程—socket(一)

从今天开始python基础就介绍完毕了,下面我们将进阶到socket网络编程的介绍,那么socket是什么呢?我们带着这个问题开始今天的介绍:

一、socket初探

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

socket其实也是一种特殊的文件,一些socket函数就是对其进行的操作(读/写、打开、关闭)

那么socket对文件操作和file对文件操作有什么区别呢?

  • file模块是针对某个指定文件进行【打开】【读写】【关闭】
  • socket模块时针对服务器和客户端Socket进行【打开】【读写】【关闭】

在介绍socket之前我们复习一下网络的OSI七层协议,方便后面的理解socket,请看下图:

TCP/IP协议是主机接入互联网以及接入互联网的两台主机通信的标准,socket直接通信同样是遵循这个标准,下面介绍socket服务端和客户端直接是如何通信的,请看下图:

下面我给大家解释一下上面这张图,我将socket之间的通信比作是电话之间通信,客户端和服务端通信必须有一个设备也就是手机或电话,然后服务端要绑定自己的手机卡并开机等待客户端打电话过来,客户端打电话过来,进行通话,这时就进入通话死循环直到双方挂电话。其实socket通信就好比打电话,首先实例化socket对象,调用socket对象中的方法,然后绑定本机的IP地址和端口,开启连接池listen(),然后阻塞accept(),直到客户端连接过来,客户端同样实例化socket对象,然后调用服务端通道conn()与服务端建立连接,这时客户端就和服务器端建立了连接,进入收发消息的死循环,直到有一方close()关闭连接,这就是整个socket的通信过程。

下面来写一个单进程的socket通信,代码如下:

Socket_Server端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socket                #导入socket模块

ip_port=(‘127.0.0.1‘,9999)   #定义主机,端口号

s=socket.socket()            #实例化socket对象(买手机)

s.bind(ip_port)              #绑定IP端口(买手机卡)

s.listen(5)                  #建立5个连接池,等待接收请求,挂起连接

#等待电话

conn,addr=s.accept()         #conn就是建立通信,负责收发消息的通道,每次只处理一个请求,

                             #accept是阻塞请求,当第二个请求来的时候会进入listen连接池

                             #挂起等待处理

while True:

    try:

        recv_data = conn.recv(1024)             #收消息

        if len(recv_data) == 0:break            #如果客户输入为空的话退出

        if recv_data == ‘exit‘:break            #客户端退出,服务端跟着退出

        send_data = recv_data.upper()          

        print(send_data)

        conn.send(send_data)                    #回复消息

    except Exception:

        break

conn.close()                                    #挂电话,关闭连接通道

Socket-Client端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socket

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()

s.connect(ip_port)    #这里的connect实际是服务端的conn,与服务端建立连接

while True:

    send_data=input(">>>: ").strip() #发送消息

    if send_data == ‘exit‘:break

    if len(send_data) == 0:continue

    s.send(bytes(send_data,encoding=‘utf-8‘))

    #收消息

    recv_data=s.recv(1024)

    print(str(recv_data,encoding=‘utf-8‘))

#挂电话

s.close()

注意:1、基于python3.*版本的socket只能收发字节bytes(),python2.*版本是可以发送字符串str()的。

          2、s.accept()和s.recv()是阻塞的,前提必须基于连接正常的情况下,连接不正常就没有阻塞的情况发生。

通过实验代码发现了一个bug,就是客户端退出,服务器端也跟着退出,那怎么让服务器端不退出呢?只要修改一个地方就可以了


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socket

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()

s.bind(ip_port)

s.listen(5)           #建立5个连接池,等待接收请求,挂起连接

while True:

    conn,addr=s.accept()

    while True:

        try:

            recv_data = conn.recv(1024)           

            if len(recv_data) == 0:break

            if recv_data == ‘exit‘:break

            send_data = recv_data.upper()         

            print(send_data)

            conn.send(send_data)

        except Exception:

            break

    conn.close()

下面我们在举一个socket的例子,我们通过socket来写一个远程执行命令的程序:

Socket_server端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import socket

import subprocess

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()

s.bind(ip_port)

s.listen(5)

while True:

    conn,addr=s.accept()

    while True:

            try:

                recv_data=conn.recv(1024)

                if len(recv_data) == 0:break

                p=subprocess.Popen(str(recv_data,encoding=‘utf8‘),shell=True,stdout=subprocess.PIPE)                                                                             

                res=p.stdout.read()

                if len(res) == 0:

                    send_data=‘cmd err‘

                else:

                    send_data=str(res,encoding=‘gbk‘)

                send_data=bytes(send_data,encoding=‘utf8‘)

                conn.send(send_data)

            except Exception:

                break

    conn.close()

Socket_Client端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socket

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()

s.connect(ip_port)

while True:

    send_data=input(">>>: ").strip()

    if send_data == ‘exit‘:break

    if len(send_data) == 0:continue

    s.send(bytes(send_data,encoding=‘utf-8‘))

    recv_data=s.recv(1024)

    print(str(recv_data,encoding=‘utf-8‘))

s.close()

执行结果:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

>>>: ls

cmd err              #执行错误命令报错

>>>: dir

2016/07/04  23:49    <DIR>          .

2016/07/04  23:49    <DIR>          ..

2016/07/03  17:55               485 socket_client.py

2016/07/04  23:44               489 socket_client1.py

2016/07/04  23:34             1,088 socket_server.py

2016/07/04  23:49               937 socket_server_cmd.py

2016/07/03  17:58               650 thread socket server.py

>>>:ipconfig /all

>>>:dir

#当我们执行完ipconfig /all命令后,再执行dir命令,还是显示的ipconfig /all的命令结果,这就涉及到了socket的一个粘包现象

大家想一下我们如何来解决socket的粘包现象,就是现在还无法判断客户端发来多少数据,导致一次无法全部接收完,请看下图:

就类似两个水桶注水一样,水桶A往水桶B注水,第一次注水10000毫升,而水桶B每次只能接收1024毫升,这时水桶A里又注入新的水,因为上次的10000毫升的水还没有完全注入水桶B中,所以还会接着注上次没有注完的水,直到将10000毫升的水注完为止,才会将新注入的水进入到B中。这就是socket粘包原理,那么怎么解决这种问题呢?

试想我们每次将注入多少水告诉水桶B,然后让水桶B做好接收同样大小水的准备就可以解决问题,有多少接收多少,具体代码如下:

Socket_Server端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import socket

import subprocess

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()          #绑定协议,生成套接字

s.bind(ip_port)            #绑定ip+协议+端口:用来唯一标识一个进程,ip_port必须是元组格式

s.listen(5)                #定义最大可以挂起的连接数

while True:                #用来重复接收新的链接

    conn,addr=s.accept()   #接收客户端胡链接请求,返回conn(相当于一个特定胡链接),addr是客户端ip+port

    while True:            #用来基于一个连接重复收发消息

            try:           #捕捉客户端异常关闭

                recv_data=conn.recv(1024)       #收消息,阻塞

                if len(recv_data) == 0:break    #客户端如果退出,服务端将收到空消息,退出

                p=subprocess.Popen(str(recv_data,encoding=‘utf8‘),shell=True,stdout=subprocess.PIPE)

                #执行系统命令,windows平台命令的标准输出是gbk编码,需要转换

                res=p.stdout.read()     #获取标准输出

                if len(res) == 0:       #执行错误命令,标准输出为空,

                    send_data=‘cmd err‘

                else:

                    send_data=str(res,encoding=‘gbk‘#命令执行ok,字节gbk---->str---->字节utf-8

                send_data=bytes(send_data,encoding=‘utf8‘)

                #解决粘包问题

                ready_tag=‘Ready|%s‘ %len(send_data)

                conn.send(bytes(ready_tag,encoding=‘utf8‘)) #先将数据大小发送给客户端,让客户端等待接收

                feedback=conn.recv(1024)                    #接收客户端确认信息

                feedback=str(feedback,encoding=‘utf8‘)

                if feedback.startswith(‘Start‘):

                    conn.send(send_data)                    #发送命令的执行结果

            except Exception:

                break

    conn.close()

Socket_Client端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import socket

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()

s.connect(ip_port)      #链接服务端,如果服务已经存在一个好的连接,那么挂起

while True:             #基于connect建立的连接来循环发送消息

    send_data=input(">>: ").strip()

    if send_data == ‘exit‘:break

    if len(send_data) == 0:continue

    s.send(bytes(send_data,encoding=‘utf8‘))

    #解决粘包问题

    ready_tag=s.recv(1024)     #收取带数据长度的字节:Ready|9998

    ready_tag=str(ready_tag,encoding=‘utf8‘)

    if ready_tag.startswith(‘Ready‘):           #判断是不是Ready开头的

        msg_size=int(ready_tag.split(‘|‘)[-1])  #获取待接收数据长度

    start_tag=‘Start‘

    s.send(bytes(start_tag,encoding=‘utf8‘))    #客户端已经准备好,发送确认信息

    #基于已经收到的待接收数据长度,循环接收数据

    recv_size=0

    recv_msg=b‘‘

    while recv_size < msg_size:

        recv_data=s.recv(1024)

        recv_msg+=recv_data

        recv_size+=len(recv_data)

        print(‘MSG SIZE %s RECE SIZE %s‘ %(msg_size,recv_size))

    print(str(recv_msg,encoding=‘utf8‘))

s.close()

上面是举的几个例子,下面介绍一下socket对象的一些功能:

 1, sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM)


1

2

3

4

5

6

7

8

参数一:地址簇

    socket.AF_INET     #IPv4(默认)

    socket.AF_INET6    #IPv6

    socket.AF_UNIX     #只能够用于单一的UNIX系统几件通信

参数二:类型

    socket.SOCK_STREAM   #流式socket,for TCP(默认)

    socket.SOCK_DGRAM    #数据报式,for UDP

2,sk.bind(address)

s.bind(address):将套接字绑定到地址。address地址的格式取决于地址簇。在AF_INET下,以元组(host,port)的形式表示地址。

3,sk.listen(backlog)

开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。

backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5,这个值不能无限大,因为要在内核中维护连接队列。

4,sk.setbloking(bool)

是否阻塞(默认为True),如果设置False,那么accept和recv时一旦无数据,则报错。

5,sk.accept()

接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据;address是连接客户端的地址,接收TCP客户的连接(阻塞式)等待连接的到来。

6,sk.connect(address)

连接到address处的套接字。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

  7,sk.connect_ex(address)

同上,只不过会有返回值,连接成功时返回0,连接失败时候返回编码,例如:10061

8,sk.close()

关闭套接字

9,sk.recv(bufsize)

接受套接字的数据,数据以字节形式返回,bufsize指定最多可以接收的数量。

 10,sk.send(bytes)

将字节数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

  11,sk.sendall(bytes)

将字节的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

内部通过递归调用send,将所有内容发送出去。

  12,sk.settimeout(timeout)

设置套接字操作的超时时间,timeout是一个浮点数,单位是秒。值为None表示没有超时期,一般超时期应该在刚创建套接字时设置,因为他们可能用于连接的操作(如client连接最多等待5s)

socket的功能就介绍到这里,更多方法请参考源码。

二、SocketServer模块

通过上面的例子我们可以发现我们的程序,都是单进程来工作,服务端一次只能处理一个请求,然而现实生产的情况下,是要支持多并发的连接,下面我们就介绍socket如何处理并发请求。

SocketServer内部使用IO多路复用以及"多线程","多进程",从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接服务器时,Socket服务端都会在服务器上创建一个"线程"或者"进程"专门负责处理当前客户端的所有请求。

Threading TCPServer:ThreadingTCPServer实现的Socket服务器内部会为每个client创建一个"线程",该线程用来和客户端进行交互。

1、ThreadingTCPServer基础

如何使用ThreadingTCPServer:

  • 创建一个继承自SocketServer.BaseRequestHandler的类;
  • 类中必须定义一个名称为handle的方法;
  • 启动ThreadingTCPServer。

请看下面的例子:

Socket_Server端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socketserver      

class MyServer(socketserver.BaseRequestHandler):

    def handle(self):

        #print self.request,self.client_address,self.server

        self.request.sendall(bytes(‘hello,world!!‘,encoding=‘utf-8‘))

        while True:

            data = self.request.recv(1024)

            if len(data) ==0:break

            print("[%s] says %s"%(self.client_address,data.decode() ))

            self.request.sendall(data.upper())

if __name__==‘__main__‘:

    server=socketserver.ThreadingTCPServer((‘127.0.0.1‘,9999),MyServer)

    server.serve_forever()

Socket_Client端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import socket

ip_port=(‘127.0.0.1‘,9999)

s=socket.socket()

s.connect(ip_port)

welcome_msg = s.recv(1024)

print("from server:",welcome_msg.decode())

while True:

    send_data=input(">>: ").strip()

    if len(send_data) == 0:continue

    s.send(bytes(send_data,encoding=‘utf8‘))

    recv_data=s.recv(1024)

    print(str(recv_data,encoding=‘utf8‘))

s.close()

2、ThreadingTCPServer源码剖析

内部调用流程为:

  • 启动服务端程序;
  • 执行TCPServer.__init__方法,创建服务端Socket对象并绑定IP和端口;
  • 执行BaseServer.__init__方法,将自定义的继承自SocketServer.BaseRequestHandler的类MyRequestHandle赋值给self.RequestHandlerClass;
  • 执行BaseServer.server_forever方法,While循环一直监听是否有客户端请求到达;
  • 当客户端请求到达服务器;
  • 执行ThreadingMixIn.process_request方法,创建一个"线程"用来处理请求;
  • 执行ThreadingMixIn.process_request_thread方法;
  • 执行BaseServer.finish_request方法,执行self.RequestHandlerClass(),即:执行自定义MyRequestHandler的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中又会调用MyRequestHandler的Handle方法)

?大概就是这个执行过程,下面在我们将上面的远程执行命令的脚本做些修改让它可以处理多并发的请求:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import socketserver

import subprocess

class MyServer(socketserver.BaseRequestHandler):

    def handle(self):

        # print self.request,self.client_address,self.server

        self.request.sendall(bytes(‘欢迎致电 10086,请输入1xxx,0转人工服务.‘,encoding="utf-8"))

        while True:

            data = self.request.recv(1024)

            if len(data) == 0:break

            print("[%s] says:%s" % (self.client_address,data.decode() ))

            cmd = subprocess.Popen(data.decode(),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

            cmd_res =cmd.stdout.read()

            if not cmd_res:

               cmd_res = cmd.stderr.read()

            if len(cmd_res) == 0: #cmd has not output

               cmd_res = bytes("cmd has output",encoding="utf-8")

            self.request.send(cmd_res )

if __name__ == ‘__main__‘:

    server = socketserver.ThreadingTCPServer((‘0.0.0.0‘,8009),MyServer)

    server.serve_forever()

下面将今天介绍的内容都串起来写个小程序,我们大家都使用过FTP来上传和下载文件,现在我们尝试自己来写一个FTP的功能,这里只实验一个FTP上传的功能:

Socket_Server端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import socketserver,json

class MyServer(socketserver.BaseRequestHandler):

    def handle(self):

        # print self.request,self.client_address,self.server

        self.request.sendall(bytes(‘欢迎致电 10086,请输入1xxx,0转人工服务.‘,encoding="utf-8"))

        while True:

            data = self.request.recv(1024)

            if len(data) == 0:break

            print("data", data)

            print("[%s] says:%s" % (self.client_address,data.decode() ))

            task_data = json.loads( data.decode()  )

            task_action = task_data.get("action")

            if hasattr(self, "task_%s"%task_action):

               func = getattr(self,"task_%s" %task_action)

               func(task_data)     

            else:

               print("task action is not supported",task_action)

    def task_put(self,*args,**kwargs):

        print("---put",args,kwargs)        

        filename = args[0].get(‘filename‘)

        filesize = args[0].get(‘file_size‘)

        server_response = {"status":200}

        self.request.send(bytes( json.dumps(server_response), encoding=‘utf-8‘  ))

        f = open(filename,‘wb‘)

        recv_size = 0

        while recv_size < filesize:

            data = self.request.recv(4096)

            f.write(data)

            recv_size += len(data)

            print(‘filesize: %s  recvsize:%s‘ % (filesize,recv_size))

        print("file recv success")

        f.close()

if __name__ == ‘__main__‘:

    server = socketserver.ThreadingTCPServer((‘0.0.0.0‘,8009),MyServer)

    server.serve_forever()

Socket_Client端:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import socket

import os ,json

ip_port=(‘192.168.11.150‘,8009)

s=socket.socket()

s.connect(ip_port)

welcome_msg = s.recv(1024)

print("from server:",welcome_msg.decode())

while True:

    send_data=input(">>: ").strip()

    if len(send_data) == 0:continue

    cmd_list = send_data.split()

    if len(cmd_list) <2:continue

    task_type = cmd_list[0]

    if task_type == ‘put‘:

        abs_filepath = cmd_list[1]

        if os.path.isfile(abs_filepath):

            file_size = os.stat(abs_filepath).st_size

            filename = abs_filepath.split("\\")[-1]

            print(‘file:%s size:%s‘ %(abs_filepath,file_size))

            msg_data = {"action":"put",

                        "filename":filename,

                        "file_size":file_size}

            s.send(  bytes(json.dumps(msg_data),encoding="utf-8")  )

            server_confirmation_msg = s.recv(1024)

            confirm_data = json.loads(server_confirmation_msg.decode())

            if confirm_data[‘status‘] ==200:

                print("start sending file ",filename)

                f = open(abs_filepath,‘rb‘)

                for line in f:

                    s.send(line)

                print("send file done ")

        else:

            print("\033[31;1mfile [%s] is not exist\033[0m" % abs_filepath)

            continue

    else:

        print("doesn‘t support task type",task_type)

        continue

    recv_data=s.recv(1024)

    print(str(recv_data,encoding=‘utf8‘))

s.close()

在这里补充一个如何在终端上打印进度条的代码,供大家参考:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#!/usr/bin/env python

#-*- coding:utf-8-*-

import time

import sys

def progress_test():

    bar_length = 20

    for percent in range(0, 101):

        hashes = ‘#‘ * int(percent / 100.0 * bar_length)

        spaces = ‘ ‘ * (bar_length - len(hashes))

        sys.stdout.write("\rPercent: [%s] %d%%" % (hashes + spaces, percent))

        sys.stdout.flush()

        time.sleep(0.1)

progress_test()

今天的socket就介绍到这里,后续会有Socket的进阶,请大家关注。

时间: 2024-10-28 18:51:26

Python网络编程—socket(一)的相关文章

python网络编程——socket进阶篇(select/poll/epoll)

原 生socket客户端在与服务端建立连接时,即服务端调用accept方法时是阻塞的,同时服务端和客户端在收数据(调用recv)时也是阻塞的.原生 socket服务端在同一时刻只能处理一个客户端请求,即服务端不能同时与多个客户端进行通信,实现并发,导致服务端资源闲置(此时服务端只占据 I/O,CPU空闲). 现在的需求是:我们要让多个客户端连接至服务器端,而且服务器端需要处理来自多个客户端请求.很明显,原生socket实现不了这种需求,此时我们该采用什么方式来处理呢? 解决方法:采用I/O多路复

python网络编程socket (一)

提起网络编程,不同于web编程,它主要是C/S架构,也就是服务器.客户端结构的.对于初学者而言,最需要理解的不是网络的概念,而是python对于网络编程都提供了些什么模块和功能.不同于计算机发展的初级阶段,程序员走到今天,已经脱离了手工打造一切,要自己实现所有细节的年代.现在提倡的是不要重复造轮子,而是学习别人的轮子怎么用,只有那些有需求或能专研的人才去设计轮子甚至汽车,so,这是一个速成的年代. 因此,对于一个面向工作的python程序员,学习python的网络编程,其实学的就是那么几个模块,

Python 网络编程——socket

一 客户端/服务器架构 客户端(Client)服务器(Server)架构,即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 理想/目标状态—— 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序,然后启动 服务.这样的服务器的任务就是接受客户的请求,把网页发给客户(如用户计算机上的浏览器),然 后等待下一个客户请求.这些服务启动后的目标就是“永远运行下去”.虽然它们不可能实现这样的 目标,但只要没有关机或硬件出错等外力干扰,它们就能运

Python网络编程-Socket简单通信

学习python中使用python进行网络编程,编写简单的客户端和服务器端进行通信,大部分内容来源于网络教程,这里进行总结供以后查阅. 先介绍下TCP的三次握手: 1,简单的发送消息: 服务器端: import socket sk = socket.socket() ip_port = ("127.0.0.1", 8888) sk.bind(ip_port) sk.listen(5) print("正在进行等待接受数据...") conn, address = sk

Python 网络编程socket大全 用途---用于客户端和服务器端之间相互通讯

本章目录 一.什么是socket 二.为什么需要socket 三.socket的发展 四.python中的socket 五.基于TCP的socket 六.基于UDP的socket 六. 粘包问题详解 七.粘包的解决方案 八.socketserver实现并发通讯 **引入:为什么一定要先学习网络协议?** 之所以学习网络编程就是为了让我们的程序能够利用网络来传输数据,开发出C/S构架的应用程序 而网络的核心,就是协议,没有协议就没有互联网,我们要开发出C/S结构程序则必须遵循这些协议的标准! `就

Python网络编程—socket套接字编程(UDP)

套接字介绍 1.套接字 : 实现网络编程进行数据传输的一种技术手段 2.Python实现套接字编程:import socket 3.套接字分类 流式套接字(SOCK_STREAM): 以字节流方式传输数据,实现tcp网络传输方案.(面向连接--tcp协议--可靠的--流式套接字) 数据报套接字(SOCK_DGRAM):以数据报形式传输数据,实现udp网络传输方案.(无连接--udp协议--不可靠--数据报套接字) UDP套接字编程 服务端流程 1.创建数据报套接字 sockfd = socket

Python网络编程—socket套接字编程(TCP)

套接字介绍 1.套接字 : 实现网络编程进行数据传输的一种技术手段 2.Python实现套接字编程:import socket 3.套接字分类 流式套接字(SOCK_STREAM): 以字节流方式传输数据,实现tcp网络传输方案.(面向连接--tcp协议--可靠的--流式套接字) 数据报套接字(SOCK_DGRAM):以数据报形式传输数据,实现udp网络传输方案.(无连接--udp协议--不可靠--数据报套接字) tcp套接字 服务端流程 1.创建套接字 sockfd=socket.socket

python网络编程-socket

python提供了两个socket模块 Socket,它提供了标准的BSD Sockets API SocketServer,它提供了服务器中心类,可以简化网络服务器的开发 下面先说socket模块 1.socket类型 套接字格式: socket(family,type[,protocal]) 使用给定的地址.套接字类型.协议编号(默认为0)来创建套接字 常用的套接字类型: socket.SOCK_STREAM      面向连接的,TCP socket.SOCK_DGRAM无连接,UDP 创

python网络编程——socket进阶篇

1 IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. linux中的IO多路复用     (1)select     select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作.     select目前几乎在所有的平台上支持