转自:
http://openexperience.iteye.com/blog/145701
python socket 模块
python 编写server的步骤:
-
第一步是创建socket对象。调用socket构造函数。如:
socket = socket.socket( family, type )
family参数代表地址家族,可为AF_INET或AF_UNIX。AF_INET家族包括Internet地址,AF_UNIX家族用于同一台机器上的进程间通信。
type参数代表套接字类型,可为SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字)。
-
第二步是将socket绑定到指定地址。这是通过socket对象的bind方法来实现的:
socket.bind( address )
由AF_INET所创建的套接字,address地址必须是一个双元素元组,格式是(host,port)。host代表主机,port代表端口号。如果端口号正在使用、主机名不正确或端口已被保留,bind方法将引发socket.error异常。
-
第三步是使用socket套接字的listen方法接收连接请求。
socket.listen( backlog )
backlog指定最多允许多少个客户连接到服务器。它的值至少为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
-
第四步是服务器套接字通过socket的accept方法等待客户请求一个连接。
connection, address = socket.accept()
调 用accept方法时,socket会时入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
-
第五步是处理阶段,服务器和客户端通过send和recv方法通信(传输 数据)。服务器调用send,并采用字符串形式向客户发送信息。send方法返回已发送的字符个数。服务器使用recv方法从客户接收信息。调用recv 时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv方法在接收数据时会进入“blocked”状态,最后返回一个字符 串,用它表示收到的数据。如果发送的数据量超过了recv所允许的,数据会被截短。多余的数据将缓冲于接收端。以后调用recv时,多余的数据会从缓冲区 删除(以及自上次调用recv以来,客户可能发送的其它任何数据)。
-
传输结束,服务器调用socket的close方法关闭连接。
python编写client的步骤:
-
创建一个socket以连接服务器:socket = socket.socket( family, type )
-
使用socket的connect方法连接服务器。对于AF_INET家族,连接格式如下:
socket.connect( (host,port) )
host代表服务器主机名或IP,port代表服务器进程所绑定的端口号。如连接成功,客户就可通过套接字与服务器通信,如果连接失败,会引发socket.error异常。
-
处理阶段,客户和服务器将通过send方法和recv方法通信。
-
传输结束,客户通过调用socket的close方法关闭连接。
下面给个简单的例子:
server.py
python 代码
-
if __name__ == '__main__':
-
import socket
-
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
sock.bind(('localhost', 8001))
-
sock.listen(5)
-
while True:
-
connection,address = sock.accept()
-
try:
-
connection.settimeout(5)
-
buf = connection.recv(1024)
-
if buf == '1':
-
connection.send('welcome to server!')
-
else:
-
connection.send('please go out!')
-
except socket.timeout:
-
print 'time out'
-
connection.close()
client.py
python 代码
-
if __name__ == '__main__':
-
import socket
-
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
sock.connect(('localhost', 8001))
-
import time
-
time.sleep(2)
-
sock.send('1')
-
print sock.recv(1024)
-
sock.close()
在终端运行server.py,然后运行clien.py,会在终端打印“welcome to server!"。如果更改client.py的sock.send('1')为其它值在终端会打印”please go out!“,更改time.sleep(2)为大于5的数值, 服务器将会超时。
转自:http://www.cnblogs.com/GarfieldTom/archive/2012/12/16/2820143.html
Python在网络通讯方面功能强大,学习一下Socket通讯的基本方式
UDP通讯:
Server:
-
import socket
-
port=8081
-
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
-
#从指定的端口,从任何发送者,接收UDP数据
-
s.bind(('',port))
-
print('正在等待接入...')
-
while True:
-
#接收一个数据
-
data,addr=s.recvfrom(1024)
-
print('Received:',data,'from',addr)
Client:
-
import socket
-
port=8081
-
host='localhost'
-
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
-
s.sendto(b'hello,this is a test info !',(host,port))
很简单 。下面是TCP方式:
Server:
-
#-*- coding: utf-8 -*-
-
from socket import *
-
from time import ctime
-
-
HOST=''
-
PORT=12345
-
BUFSIZ=1024
-
ADDR=(HOST, PORT)
-
sock=socket(AF_INET, SOCK_STREAM)
-
-
sock.bind(ADDR)
-
-
sock.listen(5)
-
while True:
-
print('waiting for connection')
-
tcpClientSock, addr=sock.accept()
-
print('connect from ', addr)
-
while True:
-
try:
-
data=tcpClientSock.recv(BUFSIZ)
-
except:
-
print(e)
-
tcpClientSock.close()
-
break
-
if not data:
-
break
-
s='Hi,you send me :[%s] %s' %(ctime(), data.decode('utf8'))
-
tcpClientSock.send(s.encode('utf8'))
-
print([ctime()], ':', data.decode('utf8'))
-
tcpClientSock.close()
-
sock.close()
Client:
-
#-*- coding: utf-8 -*-
-
from socket import *
-
-
class TcpClient:
-
HOST='127.0.0.1'
-
PORT=12345
-
BUFSIZ=1024
-
ADDR=(HOST, PORT)
-
def __init__(self):
-
self.client=socket(AF_INET, SOCK_STREAM)
-
self.client.connect(self.ADDR)
-
-
while True:
-
data=input('>')
-
if not data:
-
break
-
self.client.send(data.encode('utf8'))
-
data=self.client.recv(self.BUFSIZ)
-
if not data:
-
break
-
print(data.decode('utf8'))
-
-
if __name__ == '__main__':
-
client=TcpClient()
上面的TCP方式有个问题,不能退出,好吧,我们改造一下,使这个程序可以发送quit命令以退出:
Server:
-
#-*- coding: utf-8 -*-
-
from socket import *
-
from time import ctime
-
from time import localtime
-
import time
-
-
HOST=''
-
PORT=1122 #设置侦听端口
-
BUFSIZ=1024
-
ADDR=(HOST, PORT)
-
sock=socket(AF_INET, SOCK_STREAM)
-
-
sock.bind(ADDR)
-
-
sock.listen(5)
-
#设置退出条件
-
STOP_CHAT=False
-
while not STOP_CHAT:
-
print('等待接入,侦听端口:%d' % (PORT))
-
tcpClientSock, addr=sock.accept()
-
print('接受连接,客户端地址:',addr)
-
while True:
-
try:
-
data=tcpClientSock.recv(BUFSIZ)
-
except:
-
#print(e)
-
tcpClientSock.close()
-
break
-
if not data:
-
break
-
#python3使用bytes,所以要进行编码
-
#s='%s发送给我的信息是:[%s] %s' %(addr[0],ctime(), data.decode('utf8'))
-
#对日期进行一下格式化
-
ISOTIMEFORMAT='%Y-%m-%d %X'
-
stime=time.strftime(ISOTIMEFORMAT, localtime())
-
s='%s发送给我的信息是:%s' %(addr[0],data.decode('utf8'))
-
tcpClientSock.send(s.encode('utf8'))
-
print([stime], ':', data.decode('utf8'))
-
#如果输入quit(忽略大小写),则程序退出
-
STOP_CHAT=(data.decode('utf8').upper()=="QUIT")
-
if STOP_CHAT:
-
break
-
tcpClientSock.close()
-
sock.close()
Client:
-
#-*- coding: utf-8 -*-
-
from socket import *
-
-
class TcpClient:
-
#测试,连接本机
-
HOST='127.0.0.1'
-
#设置侦听端口
-
PORT=1122
-
BUFSIZ=1024
-
ADDR=(HOST, PORT)
-
def __init__(self):
-
self.client=socket(AF_INET, SOCK_STREAM)
-
self.client.connect(self.ADDR)
-
-
while True:
-
data=input('>')
-
if not data:
-
break
-
#python3传递的是bytes,所以要编码
-
self.client.send(data.encode('utf8'))
-
print('发送信息到%s:%s' %(self.HOST,data))
-
if data.upper()=="QUIT":
-
break
-
data=self.client.recv(self.BUFSIZ)
-
if not data:
-
break
-
print('从%s收到信息:%s' %(self.HOST,data.decode('utf8')))
-
-
-
if __name__ == '__main__':
-
client=TcpClient()
注:以上代码为Python3。
Python的Socket模块简单使用
转自:
1、使用socket模块编写UDP服务端,代码如下。从中需要注意的知识是:bind()和connect()函数都只有一个参数,参数是表示地址的元组(hostname,port),千万不要写成两个参数了。
UDP服务端,代码如下:
-
#! /usr/bin/env python
-
#coding=utf-8
-
#使用socket模块编写的服务器(通过UDP传输数据)
-
import socket
-
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
-
s.bind(("",10000)) #bind函数只有一个参数
-
while True:
-
data,client=s.recvfrom(1024)
-
print "receive a connection from %s" %str(client) #str()函数可以将元组转换成字符串形式
-
#回显
-
s.sendto("echo:"+data,client)
-
2、使用socket模块编写的UDP客户端代码:
-
#! /usr/bin/env python
-
#coding=utf-8
-
#客户端,基于UDP协议
-
import socket
-
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
-
s.sendto("hello",("localhost",10000))
-
data,addr=s.recvfrom(1024)
-
print "receive data:%s from %s" %(data,str(addr))
3、使用socket模块编写的TCP服务端
-
#! /usr/bin/env python
-
#coding=utf-8
-
import socket
-
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
-
#也可以使用s=socket.socket()来通过默认参数来生成TCP的流套接字
-
#host='' host可以为空,表示bind()函数可以绑定在所有有效地地址上
-
host="localhost"
-
port=1235
-
s.bind((host,port)) #注意,bind函数的参数只有一个,是(host,port)的元组
-
s.listen(3)
-
while True:
-
client,ipaddr=s.accept()
-
print "Got a connect from %s" %str(ipaddr)
-
data=client.recv(1024)
-
print "receive data:%s" %data
-
client.send("echo:"+data)
-
client.close()
4、使用socket模块编写的TCP客户端;
-
#! /usr/bin/env python
-
#coding=utf-8
-
import socket
-
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
-
#服务器的主机名和端口
-
-
host="localhost"
-
port=1235
-
s.connect((host,port))
-
s.send("i am client")
-
data=s.recv(1024)
-
print "Reply from server-----%s" %data
阅读(664) | 评论(0) | 转发(0) |