首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

python模块引见- socket(2)

2013-03-13 
python模块介绍- socket(2)11.1.2 TCP / IP的客户端和服务器socket可以配置为服务器或者客户端实现双向通

python模块介绍- socket(2)
11.1.2 TCP / IP的客户端和服务器

socket可以配置为服务器或者客户端实现双向通信。

简单的回显网络程序。

服务器端的步骤如下:1,创建socket(socket.socket),设定地址族和套接字类型;2,绑定地址sock.bind();3,监听sock.listen(1);4,消息处理,先用sock.accept()接收数据,然后在通道上接收connection.recv(16)或者发送数据sendall(data)。

一旦开始监听,socket就进入服务器状态。listen(1)表示只能同时接纳一个连接。

客户端的步骤如下:1,创建socket(socket.socket),设定地址族和套接字类型;2,连接sock.connect(server_address);3,消息处理,先用sock.sendall()发送数据,然后在通道上接收sock.sendall。注意跟服务器端比,这里是直接操作sock,不是connection。

 

服务器端:

#!/usr/bin/envpython

#encoding: utf-8

#

#Copyright (c) 2010 Doug Hellmann.  Allrights reserved.

#

"""Serverhalf of echo example.

"""

#end_pymotw_header

 

importsocket

importsys

 

#Create a TCP/IP socket

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

 

#Bind the socket to the port

server_address= ('localhost', 10000)

print>>sys.stderr, 'starting up on %s port %s' % server_address

sock.bind(server_address)

 

#Listen for incoming connections

sock.listen(1)

 

whileTrue:

    # Wait for a connection

    print >>sys.stderr, 'waiting for aconnection'

    connection, client_address = sock.accept()

    try:

        print >>sys.stderr, 'connectionfrom', client_address

 

        # Receive the data in small chunks andretransmit it

        while True:

            data = connection.recv(16)

            print >>sys.stderr, 'received"%s"' % data

            if data:

                print >>sys.stderr,'sending data back to the client'

                connection.sendall(data)

            else:

                print >>sys.stderr, 'nodata from', client_address

                break

           

    finally:

        # Clean up the connection

        connection.close()

客户端:

"""Clienthalf of echo example

"""

#end_pymotw_header

 

importsocket

importsys

 

#Create a TCP/IP socket

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

 

#Connect the socket to the port where the server is listening

server_address= ('localhost', 10000)

print>>sys.stderr, 'connecting to %s port %s' % server_address

sock.connect(server_address)

 

try:

   

    # Send data

    message = 'This is the message.  It will be repeated.'

    print >>sys.stderr, 'sending"%s"' % message

    sock.sendall(message)

 

    # Look for the response

    amount_received = 0

    amount_expected = len(message)

   

    while amount_received < amount_expected:

        data = sock.recv(16)

        amount_received += len(data)

        print >>sys.stderr, 'received"%s"' % data

 

finally:

    print >>sys.stderr, 'closing socket'

    sock.close()

 

执行结果:

$python ./socket_echo_server.py

startingup on localhost port 10000

waitingfor a connection

connectionfrom (’127.0.0.1’, 52186)

received"This is the mess"

sendingdata back to the client

received"age. It will be"

sendingdata back to the client

received" repeated."

sendingdata back to the client

received""

nodata from (’127.0.0.1’, 52186)

waitingfor a connection

 

$python socket_echo_client.py

connectingto localhost port 10000

sending"This is the message. It will be repeated."

received"This is the mess"

received"age. It will be"

received" repeated."

closingsocket

 

create_connection()可以更加快速的构建客户端,它使用getaddrinfo()查找连接参数,返回一个打开的socket连接,相当于省略了socket.socket(socket.AF_INET,socket.SOCK_STREAM)这一步。

 

"""Clienthalf of echo example

"""

#end_pymotw_header

 

importsocket

importsys

 

defget_constants(prefix):

    """Create a dictionarymapping socket module

    constants to their names.

    """

    return dict( (getattr(socket, n), n)

                 for n in dir(socket)

                 if n.startswith(prefix)

                 )

 

families= get_constants('AF_')

types= get_constants('SOCK_')

protocols= get_constants('IPPROTO_')

 

#Create a TCP/IP socket

sock= socket.create_connection(('localhost', 10000))

 

print>>sys.stderr, 'Family  :',families[sock.family]

print>>sys.stderr, 'Type    :',types[sock.type]

print>>sys.stderr, 'Protocol:', protocols[sock.proto]

print>>sys.stderr

 

try:

   

    # Send data

    message = 'This is the message.  It will be repeated.'

    print >>sys.stderr, 'sending"%s"' % message

    sock.sendall(message)

 

    amount_received = 0

    amount_expected = len(message)

   

    while amount_received < amount_expected:

        data = sock.recv(16)

        amount_received += len(data)

        print >>sys.stderr, 'received"%s"' % data

 

finally:

    print >>sys.stderr, 'closing socket'

    sock.close()

 

上面的服务端监听localhost,只有本机可以访问。使用gethostname()返回的地址,可以供其他机器访问。如果服务器有多个接口,也就是说有多个ip,可以使用地址:INADDR_ANY同时监听所有接口。尽管socket模块定义了INADDR_ANY常量,但是是个整型值,在传递给bind()之前需要转换为点分十进制的字符串地址。不想转换可以直接使用“0.0.0.0”或者空字符串。可以通过getsockname()查看实际监听的地址。

 

 

11.1.3 UDP的客户端和服务器

              UDP不需要建立连接,包的有效长度最大为65,507bytes,加上头部共65,535-byte。

服务器端的步骤如下:1,创建socket(socket.socket),设定地址族和套接字类型;2,绑定地址sock.bind();3,消息处理,先用sock.recvfrom(4096)接收数据,用sock.sendto(data,address)接收数据。注意这里的sendto需要加上目的地址。

客户端的步骤如下:1,创建socket(socket.socket),设定地址族和套接字类型;2消息处理,先用sock.sendto ()发送数据,然后用recvfrom接收sock.sendall。

书上的例子输出都是采用print>>sys.stderr,,我个人觉得直接print也可以。

 

 

"""Echothe data to the client without printing it on the console.

"""

#end_pymotw_header

 

importsocket

importsys

 

#Create a UDP socket

sock= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

 

#Bind the socket to the port

server_address= ('localhost', 10000)

print>>sys.stderr, 'starting up on %s port%s' % server_address

sock.bind(server_address)

 

whileTrue:

    print >>sys.stderr, '\nwaiting toreceive message'

    data, address = sock.recvfrom(4096)

   

    print >>sys.stderr, 'received %sbytes from %s' % \

        (len(data), address)

    print >>sys.stderr, data

   

    if data:

        sent = sock.sendto(data, address)

        print >>sys.stderr, 'sent %sbytes back to %s' % \

            (sent, address)

客户端如下:

"""Clienthalf of echo example

"""

#end_pymotw_header

 

importsocket

importsys

 

#Create a UDP socket

sock= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

 

server_address= ('localhost', 10000)

message= 'This is the message.  It will berepeated.'

 

try:

 

    # Send data

    print >>sys.stderr, 'sending"%s"' % message

    sent = sock.sendto(message, server_address)

 

    # Receive response

    print >>sys.stderr, 'waiting toreceive'

    data, server = sock.recvfrom(4096)

    print >>sys.stderr, 'received"%s"' % data

 

finally:

    print >>sys.stderr, 'closing socket'

    sock.close()

执行结果:

$python ./socket_echo_server_dgram.py

startingup on localhost port 10000

waitingto receive message

received42 bytes from (’127.0.0.1’, 50139)

Thisis the message. It will be repeated.

sent42 bytes back to (’127.0.0.1’, 50139)

waitingto receive message

Thisis the client output

$python ./socket_echo_client_dgram.py

sending"This is the message. It will be repeated."

waitingto receive

received"This is the message. It will be repeated."

closingsocket

这部分的程序,主要不用使用IDE去执行服务器端,否则可能会报错。

热点排行