下列关于python socket 错误的是_Python之Socket&异常处理

Socket

Socket用于描述IP地址和端口号,每个应用程序都是通过它来进行网络请求或者网络应答。

socket模块和file模块有相似之处,file主要对某个文件进行打开、读写、关闭操作。socket主要对服务端和客户端应用程序进行打开、读写、关闭。

常用方法:

sk.bind(address)

s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。

sk.listen(backlog)

开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5。这个值不能无限大,因为要在内核中维护连接队列。

sk.setblocking(bool)

是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。

sk.accept()

接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。

接收TCP 客户的连接(阻塞式)等待连接的到来。

sk.connect(address)

连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

sk.recv(bufsize[,flag])

接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。

sk.send(string[,flag])

将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

sk.sendall(string[,flag])

将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

内部通过递归调用send,将所有内容发送出去。

sk.close()

关闭套接字。

客户端与服务端socket通信示例:

服务器端:

ContractedBlock.gif

ExpandedBlockStart.gif

import socket

ip_port= ('127.0.0.1',8888)

sk=socket.socket()

sk.bind(ip_port)#向系统申请地址和端口号,并绑定

sk.listen(5)whileTrue:

print'wating...'conn,addr=sk.accept()#接收客户端的地址和端口,建立连接

client_data= conn.recv(1024)#接收客户端数据

print client_data

conn.sendall('recive your message!')

conn.close()

socket_server

客户端:

ContractedBlock.gif

ExpandedBlockStart.gif

import socket

ip_port= ('127.0.0.1',8888)

sk=socket.socket()#生成socket句柄实例

sk.connect(ip_port)#连接

sk.sendall('hello hello hello...')#向服务器端发送

server_reply= sk.recv(1024)#接收服务器回应

print server_reply

sk.close()

socket_client

连续交互示例:

服务端:

ContractedBlock.gif

ExpandedBlockStart.gif

importsocket

ip_port= ('127.0.0.1',8888)

sk=socket.socket()

sk.bind(ip_port)

sk.listen(5)whileTrue:print 'ready...'conn,addr=sk.accept()whileTrue:

client_data= conn.recv(1024)printclient_data

response= raw_input('>>')

conn.sendall(response)

conn.close()

socket_server

客户端:

ContractedBlock.gif

ExpandedBlockStart.gif

importsocket

ip_port= ('127.0.0.1',8888)

sk=socket.socket()

sk.connect(ip_port)whileTrue:

request= raw_input('>>')

sk.sendall(request)

server_reply= sk.recv(1024)printserver_reply

sk.close()

socket_client

socket实现ssh功能:

整体思路:

#服务端监听端口ip及端口,客户端发起连接请求,服务器端确认连接,并开始准备接收客户端发来的消息(循环,如果没有收到客户端发来的消息,退出循环)。#收到客户端发来的命令,执行该命令,并将该命令执行结果的大小返回给客户端(ack_msg)。#客户端收到ack_msg后,会给服务端发送确认接收命名执行结果的client_ack_msg,然后服务端开始发送执行结果(此过程是为了避免socket粘包问题)客户端开始接收,并根据ack_msg中标记的大小来循环接收命令执行结果。

服务端:

ContractedBlock.gif

ExpandedBlockStart.gif

importsocketimportos

ip_port= ('127.0.0.1',8888)

sk=socket.socket()

sk.bind(ip_port)

sk.listen(5)whileTrue:print 'Socker Server is ready...'conn,addr=sk.accept()whileTrue:

client_data= conn.recv(1024)if not client_data:#没有接受的到客户端消息,退出循环

break

printclient_data

response= os.popen(client_data).read()#获取命令执行结果

if len(response) == 0:#命令执行结果为空,告知客户端,否则客户端会一直等待接受响应

conn.sendall('command no result!')else:

ack_msg= 'cmd result size is | %s' % len(response)#将命令执行结果的长度发给客户端,‘|’符号便于客户端切割处理

conn.sendall(ack_msg)#给客户端发送ack

client_ack = conn.recv(1024)#接收客户端发来的确认接收数据ack

printclient_ackif client_ack == 'client_ready_to_recv':#确认接收到客户端发来确认接收数据的ack

conn.sendall(response)#开始发送命令执行结果

conn.close()

SSH_Server

客户端:

ContractedBlock.gif

ExpandedBlockStart.gif

importsocket

ip_port= ('127.0.0.1',8888)

sk=socket.socket()

sk.connect(ip_port)whileTrue:

cmd= raw_input('cmd:')if len(cmd) == 0:#输入为空时,继续要求输入

continue

if cmd == 'q':#输入为q时退出

breaksk.sendall(cmd)

server_ack_msg= sk.recv(1024)

cmd_res_size= int(server_ack_msg.split('|')[1])#命令执行结果的大小

printserver_ack_msgif server_ack_msg.split('|')[0] =='cmd result size is':#如果收到的是服务端发来的ack信息

print 'hello'sk.sendall('client_ready_to_recv')#给服务端发送确认接收数据的ack

res = ''recv_size=0while recv_size < cmd_res_size:#只要接收的比总大小小,就继续接收

data = sk.recv(1024)

recv_size+= len(data)#将本次接收到的大小加到已接收里

res += data#拼接接收的内容

else:printres

sk.close()

SSH_Client

以上示例都是能一对一的连接,下面是一个服务端接受多个客户端连接的实例:

服务端:

ContractedBlock.gif

ExpandedBlockStart.gif

importSocketServerclassHandler(SocketServer.BaseRequestHandler):defhandle(self):print 'new conn: %s' %str(self.client_address)whileTrue:

data= self.request.recv(1024)if notdata:break

else:print 'client said:'+data

self.request.sendall(data)if __name__ == '__main__':

host,port= 'localhost',8888server=SocketServer.ThreadingTCPServer((host,port),Handler)

server.serve_forever()

Socket_server

客户端:

ContractedBlock.gif

ExpandedBlockStart.gif

importsocket

host_port='localhost',8888sk=socket.socket()

sk.connect(host_port)whileTrue:

msg= raw_input('>>:').strip()

sk.sendall(msg)

server_reply= sk.recv(1024)print 'server reply:'+server_reply

sk.close()

Socket_client

异常处理

程序运行出现异常时,避免将该异常展现给用户。根据异常处理机制,可以自定义异常抛出信息。

没有添加异常处理:

a = range(10)print a[11]

运行结果抛出异常:IndexError: list index out of range,程序停止运行

有异常处理:

a = range(10)try:print a[11]exceptException:print '超出范围' #自定义异常提示

try:print a[11]exceptException as e:print '超出范围' #自定义异常提示

print e #系统抛出的异常

运行结果:程序正常退出

常用的异常:

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

IOError 输入/输出异常;基本上是无法打开文件

ImportError 无法引入模块或包;基本上是路径问题或名称错误

IndentationError 语法错误(的子类) ;代码没有正确对齐

IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

KeyError 试图访问字典里不存在的键

KeyboardInterrupt Ctrl+C被按下

NameError 使用一个还未被赋予对象的变量

SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)

TypeError 传入对象类型与要求的不符合

UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它

ValueError 传入一个调用者不期望的值,即使值的类型是正确的

捕获ctrl-c:

whileTrue:try:

input= raw_input('input:')exceptKeyboardInterrupt:print '请不要按ctrl+c'#输入ctrl+c后,程序依然运行。

自定义异常:

pass:关于类方法的补充

classa:def __init__(self,name):#当创建该类的一个实例时,该方法立刻执行。

self.name =namedef __str__(self):#返回字符串给用户

return 'hello %s' %self.nameif __name__ == '__main__':

p= a('ahaii')printp#运行结果:hello ahaii

classa:def __init__(self,name):

self.name=nameif __name__ == '__main__':

p= a('ahaii')printp#运行结果:< at 0x7f2b89ecff38>,只返回内存地址

自定义一个异常:

classahaiiException(Exception):def __init__(self,msg):

self.msg=msgdef __str__(self):returnself.msgtry:raise ahaiiException('自定义异常')#主动触发异常

exceptahaiiException as e:printe'自定义异常'

另外的格式:

try:

commandexceptException:

commandfinally:

command#无论是否异常,finally都会执行。

断言:assert

a = 1

assert a == 1

判断a == 1是否成立,若不成立,程序中止。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值