Python 提供了两个基本的 socket 模块。

   第一个是 Socket,它提供了标准的 BSD Sockets API。

   第二个是 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。

1、socket数据类型

  socket类型在Liunx和Python是一样的, 只是Python中的类型都定义在socket模块中, 调用方式socket.SOCK_XXXX

  1)流式socket(SOCK_STREAM) 用于TCP通信

  2)数据报socket(SOCK_DGRAM) 用于UDP通信

  3)原始socket(SOCK_RAW) 用于新的网络协议实现的测试等

  4)socket.AF_INET 用于服务器之间网络通信

 

2. Socket编程

2.1. TCP通信

 

  TCP通信的基本步骤如下:
    服务端:socket---bind---listen---while(True){---accept------send----}---close
    客户端:socket-------connect---send---recv-------close

2.2. 简单的客户端服务器TCP连接

  一个简单的回显服务器和客户端模型, 客户端发出的数据, 服务器会回显到客户端的终端上(只是一个简单的模型, 没考虑错误处理等问题)。



#服务器端
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket   #socket模块
import commands   #执行系统命令模块

BUF_SIZE = 1024  #设置缓冲区大小
server_addr = ('127.0.0.1', 8888)  #IP和端口构成表示地址
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #生成一个新的socket对象
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  #设置地址复用
server.bind(server_addr)  #绑定地址
server.listen(5)  #监听, 最大监听数为5
while True:
    client, client_addr = server.accept()  #接收TCP连接, 并返回新的套接字和地址
    print 'Connected by', client_addr
    while True :
        data = client.recv(BUF_SIZE)  #从客户端接收数据
        print data
        client.sendall(data)  #发送数据到客户端
server.close()



  



#客户端
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket

BUF_SIZE = 1024  #设置缓冲区的大小
server_addr = ('127.0.0.1', 8888)  #IP和端口构成表示地址
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #返回新的socket对象
client.connect(server_addr)  #要连接的服务器地址
while True:
    data = raw_input("Please input some string > ")  
    client.sendall(data)  #发送数据到服务器
    data = client.recv(BUF_SIZE)  #从服务器端接收数据
    print data
client.close()



  

2.3. UDP通信

UDP通信流程图如下:
服务端:socket---bind---recvfrom---sendto---close
客户端:socket---sendto---recvfrom---close

 

2.4. 简单的客户端服务器UDP连接

 

 



#服务器端
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket

BUF_SIZE = 1024  #设置缓冲区大小
server_addr = ('127.0.0.1', 8888)  #IP和端口构成表示地址
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  #生成新的套接字对象
server.bind(server_addr)  #套接字绑定IP和端口
while True :
    print "waitting for data"
    data, client_addr = server.recvfrom(BUF_SIZE)  #从客户端接收数据
    print 'Connected by', client_addr, ' Receive Data : ', data
    server.sendto(data, client_addr)  #发送数据给客户端
server.close()



 

  



#客户端
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket
import struct

BUF_SIZE = 1024  #设置缓冲区
server_addr = ('127.0.0.1', 8888)  #IP和端口构成表示地址
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  #生成新的套接字对象

while True :
    data = raw_input('Please Input data > ')
    client.sendto(data, server_addr)  #向服务器发送数据
    data, addr = client.recvfrom(BUF_SIZE)  #从服务器接收数据
    print "Data : ", data
client.close()



  

2.5. 其他

 


s.getpeername()
#返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。

s.getsockname()
#返回套接字自己的地址。通常是一个元组(ipaddr,port)

s.setsockopt(level,optname,value)
#设置给定套接字选项的值。

s.getsockopt(level,optname[.buflen])
#返回套接字选项的值。

s.settimeout(timeout)
#设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())

s.gettimeout()  
#返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。

s.fileno()
#返回套接字的文件描述符。

s.setblocking(flag)
#如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。

s.makefile()
#创建一个与该套接字相关连的文件



详见:http://www.jianshu.com/p/e062b3dd110c