pythonsocket,Pythonsocket反向监听
python怎样建立socket服务器
下面的例子是多线程实现的socket服务器:
import socketimport threadingclass ThreadedServer(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
def listen(self):
self.sock.listen(5)
while True:
client, address = self.sock.accept()
client.settimeout(60)
threading.Thread(target = self.listenToClient,args = (client,address)).start()
def listenToClient(self, client, address):
size = 1024
while True:
try:
data = client.recv(size)
if data:
# Set the response to echo back the recieved data
response = data
client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return Falseif __name__ == "__main__":
while True:
port_num = input("Port? ")
try:
port_num = int(port_num)
break
except ValueError:
pass
ThreadedServer('',port_num).listen()
python怎么建立socket服务端
socket服务器再细分可分为多种了,tcp,udp,websocket,都是调用socket模块,但是具体实现起来有一点细微的差别
先给出一个tcp和udp通过socket协议实现的聊天室的例子
python聊天室(python2.7版本):
都是分别运行server.py和client.py,就可以进行通讯了。
TCP版本:
socket-tcp-server.py(服务端):
?
#-*-?encoding:utf-8?-*-
#socket.getaddrinfo(host,??port,?family=0,?socktype=0,?proto=0,?flags=0)
#根据给定的参数host/port,相应的转换成一个包含用于创建socket对象的五元组,
#参数host为域名,以字符串形式给出代表一个IPV4/IPV6地址或者None.
#参数port如果字符串形式就代表一个服务名,比如“http”"ftp""email"等,或者为数字,或者为None
#参数family为地主族,可以为AF_INET??,AF_INET6?,AF_UNIX.
#参数socktype可以为SOCK_STREAM(TCP)或者SOCK_DGRAM(UDP)
#参数proto通常为0可以直接忽略
#参数flags为AI_*的组合,比如AI_NUMERICHOST,它会影响函数的返回值
#附注:给参数host,port传递None时建立在C基础,通过传递NULL。
#该函数返回一个五元组(family,?socktype,?proto,?canonname,?sockaddr),同时第五个参数sockaddr也是一个二元组(address,?port)
#更多的方法及链接请访问
#?Echo?server?program
from?socket?import?*
import?sys
import?threading
from?time?import?ctime
from?time?import?localtime
import?traceback
import?time
import?subprocess
reload(sys)
sys.setdefaultencoding("utf8")
?
?
HOST='127.0.0.1'
PORT=8555??#设置侦听端口
BUFSIZ=1024
?
class?TcpServer():
????def?__init__(self):
????????self.ADDR=(HOST,?PORT)
????????try:
????????????self.sock=socket(AF_INET,?SOCK_STREAM)
????????????print?'%d?is?open'?%?PORT
?
????????????self.sock.bind(self.ADDR)
????????????self.sock.listen(5)
????????????#设置退出条件
????????????self.STOP_CHAT=False
?
????????????#?所有监听的客户端
????????????self.clients?=?{}
????????????self.thrs?=?{}
????????????self.stops?=?[]
?
????????except?Exception,e:
????????????print?"%d?is?down"?%?PORT
????????????return?False
?
????def?IsOpen(ip,?port):
?
????????s?=?socket(AF_INET,?SOCK_STREAM)
????????try:
????????????s.connect((ip,?int(port)))
????????????#?s.shutdown(2)
????????????#?利用shutdown()函数使socket双向数据传输变为单向数据传输。shutdown()需要一个单独的参数,
????????????#?该参数表示s了如何关闭socket。具体为:0表示禁止将来读;1表示禁止将来写;2表示禁止将来读和写。
????????????print?'%d?is?open'?%?port
????????????return?True
????????except:
????????????print?'%d?is?down'?%?port
????????????return?False
?
????def?listen_client(self):
????????while?not?self.STOP_CHAT:
????????????print(u'等待接入,侦听端口:%d'?%?(PORT))
????????????self.tcpClientSock,?self.addr=self.sock.accept()
????????????print(u'接受连接,客户端地址:',self.addr)
????????????address?=?self.addr
????????????#将建立的client?socket链接放到列表self.clients中
????????????self.clients[address]?=?self.tcpClientSock
????????????#分别将每个建立的链接放入进程中,接收且分发消息
????????????self.thrs[address]?=?threading.Thread(target=self.readmsg,?args=[address])
????????????self.thrs[address].start()
????????????time.sleep(0.5)
?
?
?
????def?readmsg(self,address):
????????#如果地址不存在,则返回False
????????if?address?not?in?self.clients:
????????????return?False
????????#得到发送消息的client?socket
????????client?=?self.clients[address]
????????while?True:
????????????try:
????????????????#获取到消息内容data
????????????????data=client.recv(BUFSIZ)
????????????except:
????????????????print(e)
????????????????self.close_client(address)
????????????????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=u'%s发送给我的信息是:%s'?%(str(address),data.decode('utf8'))
????????????#将获得的消息分发给链接中的client?socket
????????????for?k?in?self.clients:
????????????????self.clients[k].send(s.encode('utf8'))
????????????????self.clients[k].sendall('sendall:'+s.encode('utf8'))
????????????????print?str(k)
????????????print([stime],?':',?data.decode('utf8'))
????????????#如果输入quit(忽略大小写),则程序退出
????????????STOP_CHAT=(data.decode('utf8').upper()=="QUIT")
????????????if?STOP_CHAT:
????????????????print?"quit"
????????????????self.close_client(address)
????????????????print?"already?quit"
????????????????break
?
????def?close_client(self,address):
????????try:
????????????client?=?self.clients.pop(address)
????????????self.stops.append(address)
????????????client.close()
????????????for?k?in?self.clients:
????????????????self.clients[k].send(str(address)?+?u"已经离开了")
????????except:
????????????pass
????????print(str(address)+u'已经退出')
?
?
if?__name__?==?'__main__':
????tserver?=?TcpServer()
????tserver.listen_client()
?????
?——————————华丽的分割线——————————???????
?????
?socket-tcp-client.py?(客户端):
??
#-*-?encoding:utf-8?-*-
from?socket?import?*
import?sys
import?threading
import?time
reload(sys)
sys.setdefaultencoding("utf8")
?
?
#测试,连接本机
HOST='127.0.0.1'
#设置侦听端口
PORT=8555
BUFSIZ=1024
?
class?TcpClient:
?
????ADDR=(HOST,?PORT)
????def?__init__(self):
????????self.HOST?=?HOST
????????self.PORT?=?PORT
????????self.BUFSIZ?=?BUFSIZ
????????#创建socket连接
????????self.client?=?socket(AF_INET,?SOCK_STREAM)
????????self.client.connect(self.ADDR)
????????#起一个线程,监听接收的信息
????????self.trecv?=?threading.Thread(target=self.recvmsg)
????????self.trecv.start()
?
????def?sendmsg(self):
????????#循环发送聊天消息,如果socket连接存在则一直循环,发送quit时关闭链接
????????while?self.client.connect_ex(self.ADDR):
????????????data=raw_input(':')
????????????if?not?data:
????????????????break
????????????self.client.send(data.encode('utf8'))
????????????print(u'发送信息到%s:%s'?%(self.HOST,data))
????????????if?data.upper()=="QUIT":
????????????????self.client.close()
????????????????print?u"已关闭"
????????????????break
????def?recvmsg(self):
????????#接收消息,如果链接一直存在,则持续监听接收消息
????????try:
????????????while?self.client.connect_ex(self.ADDR):
????????????????data=self.client.recv(self.BUFSIZ)
????????????????print(u'从%s收到信息:%s'?%(self.HOST,data.decode('utf8')))
????????except?Exception,e:
????????????print?str(e)
?
if?__name__?==?'__main__':
????client=TcpClient()
????client.sendmsg()
UDP版本:
socket-udp-server.py
?
#?-*-?coding:utf8?-*-
?
import?sys
import?time
import?traceback
import?threading
reload(sys)
sys.setdefaultencoding('utf-8')
?
import?socket
import?traceback
?
HOST?=?"127.0.0.1"
PORT?=?9555
CHECK_PERIOD?=?20
CHECK_TIMEOUT?=?15
?
class?UdpServer(object):
????def?__init__(self):
????????self.clients?=?[]
????????self.beats?=?{}
????????self.ADDR?=?(HOST,PORT)
????????try:
????????????self.sock?=?socket.socket(socket.AF_INET,?socket.SOCK_DGRAM)
????????????self.sock.bind(self.ADDR)???????#?绑定同一个域名下的所有机器
????????????self.beattrs?=?threading.Thread(target=self.checkheartbeat)
????????????self.beattrs.start()
????????except?Exception,e:
????????????traceback.print_exc()
????????????return?False
?
????def?listen_client(self):
????????while?True:
????????????time.sleep(0.5)
????????????print?"hohohohohoo"
????????????try:
????????????????recvData,address?=?self.sock.recvfrom(2048)
????????????????if?not?recvData:
????????????????????self.close_client(address)
????????????????????break
????????????????if?address?in?self.clients:
????????????????????senddata?=?u"%s发送给我的信息是:%s"?%(str(address),recvData.decode('utf8'))
????????????????????if?recvData.upper()?==?"QUIT":
????????????????????????self.close_client(address)
????????????????????if?recvData?==?"HEARTBEAT":
????????????????????????self.heartbeat(address)
????????????????????????continue
????????????????else:
????????????????????self.clients.append(address)
????????????????????senddata?=?u"%s发送给我的信息是:%s"?%(str(address),u'进入了聊天室')
????????????????for?c?in?self.clients:
????????????????????try:
????????????????????????self.sock.sendto(senddata,c)
????????????????????except?Exception,e:
????????????????????????print?str(e)
????????????????????????self.close_client(c)
????????????except?Exception,e:
????????????????#?traceback.print_exc()
????????????????print?str(e)
????????????????pass
?
????def?heartbeat(self,address):
????????self.beats[address]?=?time.time()
?
????def?checkheartbeat(self):
?
????????while?True:
????????????print?"checkheartbeat"
????????????print?self.beats
????????????try:
????????????????for?c?in?self.clients:
????????????????????print?time.time()
????????????????????print?self.beats[c]
????????????????????if?self.beats[c]?+?CHECK_TIMEOUT?time.time():
????????????????????????print?u"%s心跳超时,连接已经断开"?%str(c)
????????????????????????self.close_client(c)
????????????????????else:
????????????????????????print?u"checkp%s,没有断开"?%str(c)
????????????except?Exception,e:
????????????????traceback.print_exc()
????????????????print?str(e)
????????????????pass
????????????time.sleep(CHECK_PERIOD)
?
????def?close_client(self,address):
????????try:
????????????if?address?in?self.clients:
????????????????self.clients.remove(address)
????????????????if?self.beats.has_key(address):
????????????????????del?self.beats[address]
????????????????print?self.clients
????????????for?c?in?self.clients:
????????????????self.sock.sendto(u'%s已经离开了'?%?str(address),c)
????????????print(str(address)+u'已经退出')
????????except?Exception,e:
????????????print?str(e)
????????????raise
?
if?__name__?==?"__main__":
????udpServer?=?UdpServer()
????udpServer.listen_client()
?????
——————————华丽的分割线——————————????
socket-udp-client.py:
#?-*-?coding:utf8?-*-
?
import?sys
import?threading
import?time
reload(sys)
sys.setdefaultencoding('utf-8')
?
import?socket
?
HOST?=?"127.0.0.1"
PORT?=?9555
#BEAT_PORT?=?43278
BEAT_PERIOD?=?5
?
?
class?UdpClient(object):
????def?__init__(self):
????????self.clientsock?=?socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
????????self.HOST?=?HOST
????????self.ADDR?=?(HOST,PORT)
????????self.clientsock.sendto(u'请求建立链接',self.ADDR)
????????self.recvtrs?=?threading.Thread(target=self.recvmsg)
????????self.recvtrs.start()
????????self.hearttrs?=?threading.Thread(target=self.heartbeat)
????????self.hearttrs.start()
?
????def?sendmsg(self):
????????while?True:
????????????data?=?raw_input(":")
????????????if?not?data:
????????????????break
????????????self.clientsock.sendto(data.encode('utf-8'),self.ADDR)
????????????if?data.upper()?==?'QUIT':
????????????????self.clientsock.close()
????????????????break
?
????def?heartbeat(self):
????????while?True:
????????????self.clientsock.sendto('HEARTBEAT',self.ADDR)
????????????time.sleep(BEAT_PERIOD)
?
????def?recvmsg(self):
????????while?True:
????????????recvData,addr?=?self.clientsock.recvfrom(1024)
????????????if?not?recvData:
????????????????break
????????????print(u'从%s收到信息:%s'?%(self.HOST,recvData.decode('utf8')))
?
?
?
if?__name__?==?"__main__":
????udpClient?=?UdpClient()
????udpClient.sendmsg()
Python socket 模块
Python 提供了两个基本的 socket 模块。第一个是 Socket,它提供了标准的 BSD Sockets API。第二个是 SocketServer,它提供了服务器中心类,可以简化网络服务器的开发。
Socket 模块提供了 UNIX ? 程序员所熟悉的基本网络服务(也称为 BSD API)。这个模块中提供了在构建 socket 服务器和客户机时所需要的所有功能。
在 Python 中,socket 方法会向应用 socket 方法的对象返回一个 socket 对象。
pythonsocket获取数据代码
pythonsocket使用request方法获取数据代码。socket.socket函数的前两个参数的默认值是socket.AF_INET和socket.SOCK_STREAM,创建TCPsocket时可以直接写成socket.socket()。然后使用request方法就可以获取数据代码了。
Python 之 Socket编程(TCP/UDP)
socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。
有效的端口号: 0~ 65535
但是小于1024的端口号基本上都预留给了操作系统
POSIX兼容系统(如Linux、Mac OS X等),在/etc/services文件中找到这些预留端口与的列表
面向连接的通信提供序列化、可靠的和不重复的数据交付,而没有记录边界。意味着每条消息都可以拆分多个片段,并且每个消息片段都能到达目的地,然后将它们按顺序组合在一起,最后将完整的信息传递给等待的应用程序。
实现方式(TCP):
传输控制协议(TCP), 创建TCP必须使用SOCK_STREAM作为套接字类型
因为这些套接字(AF_INET)的网络版本使用因特网协议(IP)来搜寻网络中的IP,
所以整个系统通常结合这两种协议(TCP/IP)来进行网络间数据通信。
数据报类型的套接字, 即在通信开始之前并不需要建议连接,当然也无法保证它的顺序性、可靠性或重复性
实现方式(UDP)
用户数据包协议(UDP), 创建UDP必须使用SOCK_DGRAM (datagram)作为套接字类型
它也使用因特网来寻找网络中主机,所以是UDP和IP的组合名字UDP/IP
注意点:
1)TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的,每次发送要指定是发给谁。
2)服务端与客户端不能直接发送列表,元组,字典。需要字符串化repr(data)。
TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
什么时候应该使用TCP : 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输.
UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击……
UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 TFTP ……
python socket编程
通过python的网络通信支持,通过网络模块,python程序可以非常方便地相互访问互联网上的HTTP服务和FTP服务等。可以直接获取互联网上的远程资源,还可以向远程资源发送GET POST请求。
计算机网络是线代通信技术与计算机技术相结合的产物,计算机网络主要可以提供
通信协议一般由三部分组成:一是语义部分,用于决定双方对话类型;二是语法部分,用于决定双方对话的格式;三是变化规则,用于决定通信双方的应答关系。
应用层:与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的。有HTTP, FTP , NFS, SMTP, TELNET
表示层:这一层主要是定义数据格式及加密。如加密, ASCII
会话层:它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的。如 RPC,SQL
传输层:这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在泳衣主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能,如 TCP UDP SPX
网络层:这层对端对端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。如IP
数据链路层:它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关
物理层:OSI的物理层规范是有关传输介质的特性,这些规范通常也参考了其他组织制定的标准。
IP地址用于唯一标识网络中的一个通信实体,这个通信实体既可以是一个主机,也可以是路由器的某个端口,。而在基于IP协议的网络中传输数据包都必须使用IP地址来进行标识。
端口,程序与外界进行交互的出入口。
Tcp/IP通信协议是一种可靠的网络协议,他在通信的两端建立一个socket,从而形成虚拟的网络链路。一旦建立了虚拟网络链路,两端的程序就可以通过该链路进行通信。
IP 是Internet上使用的一个关键协议,通过IP协议,使internet成为一个允许连接不同类型的计算机和不同操作系统的网络。同时还需要TCP协议来提供可靠且无差错的服务。
TCP协议被称为端对端协议,这是因为他在两台计算机的连接中起了非常重要的角色,当一台计算机需要与另外一台计算机连接时,TCP协议会让他们之间建立一个虚拟链路,用于发送和接受数据。
TCP协议负责收集这些数据包,并将其按照适当的顺序传送,接收端收到数据包后将其正确的还原。TCP保证数据包在传送过程中准确无误。TCP协议采用重发机制,当一个通信实体发送一个消息给另外一个通信实体后,需要接收到另外一个通信实体的确认信息,如果没有接收到该确认信息,则会重发信息。
使用socket之前,必须先创建socket对象,可通过该类的构造器来创建socket实例。
socket.socket(family = AF_INET, type= SOCK_STREAM, proto=0, fileno= None)
socket对象常用的方法:
基本步骤
创建客户端的步骤:
小实例:服务端
客户端:
通过这样就可以实现socket之间的通信。