Python 的 Socket 编程教程.docx

上传人:b****6 文档编号:4322143 上传时间:2022-11-29 格式:DOCX 页数:22 大小:22.22KB
下载 相关 举报
Python 的 Socket 编程教程.docx_第1页
第1页 / 共22页
Python 的 Socket 编程教程.docx_第2页
第2页 / 共22页
Python 的 Socket 编程教程.docx_第3页
第3页 / 共22页
Python 的 Socket 编程教程.docx_第4页
第4页 / 共22页
Python 的 Socket 编程教程.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

Python 的 Socket 编程教程.docx

《Python 的 Socket 编程教程.docx》由会员分享,可在线阅读,更多相关《Python 的 Socket 编程教程.docx(22页珍藏版)》请在冰豆网上搜索。

Python 的 Socket 编程教程.docx

Python的Socket编程教程

这是用来快速学习PythonSocket套接字编程的指南和教程。

Python的Socket编程跟C语言很像。

Python官方关于Socket的函数请看 http:

//docs.python.org/library/socket.html

基本上,Socket是任何一种计算机网络通讯中最基础的内容。

例如当你在浏览器地址栏中输入时,你会打开一个套接字,然后连接到并读取响应的页面然后然后显示出来。

而其他一些聊天客户端如gtalk和skype也是类似。

任何网络通讯都是通过Socket来完成的。

写在开头

本教程假设你已经有一些基本的Python编程的知识。

让我们开始Socket编程吧。

创建Socket

首先要做的就是创建一个Socket,socket的socket函数可以实现,代码如下:

Code

1

2

3

4

5

6

7

8

#Socketclientexampleinpython

 

importsocket  #forsockets

 

#createanAF_INET,STREAMsocket(TCP)

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

 

print'SocketCreated'

函数socket.socket创建了一个Socket,并返回Socket的描述符可用于其他Socket相关的函数。

上述代码使用了下面两个属性来创建Socket:

地址簇:

AF_INET(IPv4)

类型:

SOCK_STREAM(使用TCP传输控制协议)

错误处理

如果socket函数失败了,python将抛出一个名为socket.error的异常,这个异常必须予以处理:

Code

1

2

3

4

5

6

7

8

9

10

11

12

13

#handlingerrorsinpythonsocketprograms

 

importsocket  #forsockets

importsys #forexit

 

try:

    #createanAF_INET,STREAMsocket(TCP)

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

exceptsocket.error,msg:

    print'Failedtocreatesocket.Errorcode:

'+str(msg[0])+',Errormessage:

'+msg[1]

    sys.exit();

 

print'SocketCreated'

好了,假设你已经成功创建了Socket,下一步该做什么呢?

接下来我们将使用这个Socket来连接到服务器。

注意

与SOCK_STREAM相对应的其他类型是SOCK_DGRAM用于UDP通讯协议,UDP通讯是非连接Socket,在这篇文章中我们只讨论SOCK_STREAM,或者叫TCP。

连接到服务器

连接到服务器需要服务器地址和端口号,这里使用的是和80端口。

首先获取远程主机的IP地址

连接到远程主机之前,我们需要知道它的IP地址,在Python中,获取IP地址是很简单的:

Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

importsocket  #forsockets

importsys #forexit

 

try:

    #createanAF_INET,STREAMsocket(TCP)

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

exceptsocket.error,msg:

    print'Failedtocreatesocket.Errorcode:

'+str(msg[0])+',Errormessage:

'+msg[1]

    sys.exit();

 

print'SocketCreated'

 

host=''

 

try:

    remote_ip=socket.gethostbyname(host)

 

exceptsocket.gaierror:

    #couldnotresolve

    print'Hostnamecouldnotberesolved.Exiting'

    sys.exit()

     

print'Ipaddressof'+host+'is'+remote_ip

我们已经有IP地址了,接下来需要指定要连接的端口。

代码:

Code

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

importsocket  #forsockets

importsys #forexit

 

try:

    #createanAF_INET,STREAMsocket(TCP)

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

exceptsocket.error,msg:

    print'Failedtocreatesocket.Errorcode:

'+str(msg[0])+',Errormessage:

'+msg[1]

    sys.exit();

 

print'SocketCreated'

 

host=''

port=80

 

try:

    remote_ip=socket.gethostbyname(host)

 

exceptsocket.gaierror:

    #couldnotresolve

    print'Hostnamecouldnotberesolved.Exiting'

    sys.exit()

     

print'Ipaddressof'+host+'is'+remote_ip

 

#Connecttoremoteserver

s.connect((remote_ip,port))

 

print'SocketConnectedto'+host+'onip'+remote_ip

现在运行程序

1

2

3

4

$pythonclient.py

SocketCreated

Ipaddressofis61.145.122.155

SocketConnectedtoonip61.145.122.155

这段程序创建了一个Socket并进行连接,试试使用其他一些不存在的端口(如81)会是怎样?

这个逻辑相当于构建了一个端口扫描器。

已经连接上了,接下来就是往服务器上发送数据。

免费提示

使用SOCK_STREAM/TCP套接字才有“连接”的概念。

连接意味着可靠的数据流通讯机制,可以同时有多个数据流。

可以想象成一个数据互不干扰的管道。

另外一个重要的提示是:

数据包的发送和接收是有顺序的。

其他一些Socket如UDP、ICMP和ARP没有“连接”的概念,它们是无连接通讯,意味着你可从任何人或者给任何人发送和接收数据包。

发送数据

sendall函数用于简单的发送数据,我们来向oschina发送一些数据:

Code

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

importsocket  #forsockets

importsys #forexit

 

try:

    #createanAF_INET,STREAMsocket(TCP)

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

exceptsocket.error,msg:

    print'Failedtocreatesocket.Errorcode:

'+str(msg[0])+',Errormessage:

'+msg[1]

    sys.exit();

 

print'SocketCreated'

 

host=''

port=80

 

try:

    remote_ip=socket.gethostbyname(host)

 

exceptsocket.gaierror:

    #couldnotresolve

    print'Hostnamecouldnotberesolved.Exiting'

    sys.exit()

     

print'Ipaddressof'+host+'is'+remote_ip

 

#Connecttoremoteserver

s.connect((remote_ip,port))

 

print'SocketConnectedto'+host+'onip'+remote_ip

 

#Sendsomedatatoremoteserver

message="GET/HTTP/1.1\r\n\r\n"

 

try:

    #Setthewholestring

    s.sendall(message)

exceptsocket.error:

    #Sendfailed

    print'Sendfailed'

    sys.exit()

 

print'Messagesendsuccessfully'

上述例子中,首先连接到目标服务器,然后发送字符串数据"GET/HTTP/1.1\r\n\r\n",这是一个HTTP协议的命令,用来获取网站首页的内容。

接下来需要读取服务器返回的数据。

接收数据

recv函数用于从socket接收数据:

Code

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

#Socketclientexampleinpython

 

importsocket  #forsockets

importsys #forexit

 

#createanINET,STREAMingsocket

try:

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

exceptsocket.error:

    print'Failedtocreatesocket'

    sys.exit()

     

print'SocketCreated'

 

host='';

port=80;

 

try:

    remote_ip=socket.gethostbyname(host)

 

exceptsocket.gaierror:

    #couldnotresolve

    print'Hostnamecouldnotberesolved.Exiting'

    sys.exit()

 

#Connecttoremoteserver

s.connect((remote_ip,port))

 

print'SocketConnectedto'+host+'onip'+remote_ip

 

#Sendsomedatatoremoteserver

message="GET/HTTP/1.1\r\nHost:

\r\n\r\n"

 

try:

    #Setthewholestring

    s.sendall(message)

exceptsocket.error:

    #Sendfailed

    print'Sendfailed'

    sys.exit()

 

print'Messagesendsuccessfully'

 

#Nowreceivedata

reply=s.recv(4096)

 

printreply

下面是上述程序执行的结果:

Code

1

2

3

4

5

6

7

8

9

10

11

12

13

$pythonclient.py

SocketCreated

Ipaddressofis61.145.122.

SocketConnectedtoonip61.145.122.155

Messagesendsuccessfully

HTTP/1.1301MovedPermanently

Server:

nginx

Date:

Wed,24Oct201213:

26:

46GMT

Content-Type:

text/html

Content-Length:

178

Connection:

keep-alive

Keep-Alive:

timeout=20

Location:

回应了我们所请求的URL的内容,很简单。

数据接收完了,可以关闭Socket了。

关闭socket

close函数用于关闭Socket:

Code

1

s.close()

这就是了。

让我们回顾一下

上述的示例中我们学到了如何:

1.创建Socket

2.连接到远程服务器

3.发送数据

4.接收回应

当你用浏览器打开时,其过程也是一样。

包含两种类型,分别是客户端和服务器,客户端连接到服务器并读取数据,服务器使用Socket接收进入的连接并提供数据。

因此在这里是服务器端,而你的浏览器是客户端。

接下来我们开始在服务器端做点编码。

服务器端编程

服务器端编程主要包括下面几步:

1.打开socket

2.绑定到一个地址和端口

3.侦听进来的连接

4.接受连接

5.读写数据

我们已经学习过如何打开Socket了,下面是绑定到指定的地址和端口上。

绑定Socket

bind函数用于将Socket绑定到一个特定的地址和端口,它需要一个类似connect函数所需的sockaddr_in结构体。

示例代码:

Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

importsocket

importsys

 

HOST=''  #Symbolicnamemeaningallavailableinterfaces

PORT=8888#Arbitrarynon-privilegedport

 

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

print'Socketcreated'

 

try:

    s.bind((HOST,PORT))

exceptsocket.error,msg:

    print'Bindfailed.ErrorCode:

'+str(msg[0])+'Message'+msg[1]

    sys.exit()

     

print'Socketbindcomplete'

绑定完成后,就需要让Socket开始侦听连接。

很显然,你不能将两个不同的Socket绑定到同一个端口之上。

连接侦听

绑定Socket之后就可以开始侦听连接,我们需要将Socket变成侦听模式。

socket的listen函数用于实现侦听模式:

Code

1

2

s.listen(10)

print'Socketnowlistening'

listen函数所需的参数成为backlog,用来控制程序忙时可保持等待状态的连接数。

这里我们传递的是10,意味着如果已经有10个连接在等待处理,那么第11个连接将会被拒绝。

当检查了socket_accept后这个会更加清晰。

接受连接

示例代码:

Code

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

importsocket

importsys

 

HOST=''  #Symbolicnamemeaningallavailableinterfaces

PORT=8888#Arbitrarynon-privilegedport

 

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

print'Socketcreated'

 

try:

    s.bind((HOST,PORT))

exceptsocket.error,msg:

    print'Bindfailed.ErrorCode:

'+str(msg[0])+'Message'+msg[1]

    sys.exit()

     

print'Socketbindcomplete'

 

s.listen(10)

print'Socketnowlistening'

 

#waittoacceptaconnection-blockingcall

conn,addr=s.accept()

 

#displayclientinformation

print'Connectedwith'+addr[0]+':

'+str(addr[1])

输出

运行该程序将会显示:

1

2

3

4

$pythonserver.py

Socketcreated

Socketbindcomplete

Socketnowlistening

现在这个程序开始等待连接进入,端口是8888,请不要关闭这个程序,我们来通过telnet程序来进行测试。

打开命令行窗口并输入:

1

2

3

4

5

6

7

8

$telnetlocalhost8888

 

Itwillimmediatelyshow

$telnetlocalhost8888

Trying127.0.0.1...

Connectedtolocalhost.

Escapecharacteris'^]'.

Connectionclosedbyforeignhost.

而服务器端窗口显示的是:

1

2

3

4

5

$pythonserver.py

Socketcreated

Socketbindcomplete

Socketnowlistening

Connectedwith127.0.0.1:

59954

我们可看到客户端已经成功连接到服务器。

上面例子我们接收到连接并立即关闭,这样的程序没什么实际的价值,连接建立后一般会有大量的事情需要处理,因此让我们来给客户端做出点回应吧。

sendall函数可通过Socket给客户端发送数据:

Code

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

importsocket

importsys

 

HOST=''  #Symbolicnamemeaningallavailableinterfaces

PORT=8888#Arbitrarynon-privilegedport

 

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

print'Socketcreated'

 

try:

    s.bind((HOST,PORT))

exceptsocket.error,msg:

    print'Bindfailed.ErrorCode:

'+str(msg[0])+'Message'+msg[1]

    sys.exit()

     

print'Socketbindcomplete'

 

s.listen(10)

print'Socketnowlistening'

 

#waittoacceptaconnection-blockingcall

conn,addr=s.accept()

 

print'Connectedwith'+addr[0]+':

'+str(addr[1])

 

#nowkeeptalkingwiththeclient

data=conn.recv(1024)

conn.sendall(data)

 

conn.close()

s.close()

继续运行

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1