求教:关于socket的recv

sinco449 2008-01-30 06:00:22
本人使用该程序与一台本地通信设备建立数据通信.发送正常的帧(MsgList)时,recv方法能够接收到数据。但如果发送非正常的帧(即通信设备不会应答该帧),则程序就一直阻塞在recv方法那里,无法抛出异常。请教各位,怎么使得程序可以检查出对方无数据从socket发送过来,从而让recv抛出异常。使用select来检查吗?
(附:本人使用while的原因是由于应答帧可能是由远程通信设备产生,经过本地设备中转而来,这中间需要消耗一定的时间,当发生超时时就不处理)
import socket
import struct
import time

MsgStruct = ""
mysock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
mysock.connect(('192.192.4.2',3000))
except socket.error:
sys.exit("Connect failed")
MsgList =[150, 3, 192, 192, 4, 2, 192, 192, 4, 230, 0, 0, 0, 0, 0, 1, 0, 2, 17, 0, 0, 0, 4, 158]
for num in MsgList:
MsgStruct = MsgStruct + struct.pack('@B',num)
try:
mysock.send(MsgStruct)
except error:
mysock.close()

timeout = 5000
tStart = time.time( )
while( 1 ):
tFinish = time.time( )
WaitTime = int( (tFinish - tStart)*1000 )
if WaitTime > timeout:
break
try:
Msg = mysock.recv( 4096 )
if Msg == ' ':
raise error
except:
continue
mysock.close()
...全文
604 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
sinco449 2008-03-03
  • 打赏
  • 举报
回复
该问题解决了,多谢各位的指导。
我的方法是在 tStart = time.time( )后面加一行代码:“mysock.settimeout(0.0)”,将socket置为非阻塞状态。
l1423 2008-02-24
  • 打赏
  • 举报
回复
这个是不行的。
socket的recv默认是阻塞的,虽然可以利用ioctl来设置为不阻塞,但这应该不是你想要的。因为不阻塞的时候,只能是你确保数据刚好在你调用recv的时候已经到来了,否则根据接收不到数据就返回了。
可以使用select。
当然select也只能在收到数据后才返回,否则也是一直阻塞。不过select可以设置超时时间,时间一到没有数据也可以返回。
linux_328 2008-02-21
  • 打赏
  • 举报
回复
recv函数是一直Block的,直到对方有数据发过来或者对方close了,你说的recv抛出异常应该不是因为对方把socket close了抛出的异常,而是在你发出数据一定时候后收不到对方数据的异常,可以用select,select用法如下
int select(
int nfds, //该参数你可以忽略
fd_set* readfds, //该参数指向的数据结构加入你等待接受数据的socket
fd_set* writefds, //该参数可以忽略
fd_set* exceptfds, // 该参数可以忽略
const struct timeval* timeout // 该参数为你timeout的时间
); // 返回值为你的socket可以读的数据大小,如果为0,表明超时,对方无数据发过来。recv方法将被block

还有一个方法可以用
int ioctlsocket(
SOCKET s, //你准备接受数据的socket
long cmd, // 设置为FIONREAD,表明你的socket可读的数据
u_long* argp // 指向一个unsigned long 类型,用来存放你可以读的数据
);



亲密数 2008-01-31
  • 打赏
  • 举报
回复
用While循环是没什么效率的。可以采用异步I/O的方式。
使用select来检查吗?可以。


import socket
import struct
import time
import select
import sys

MsgStruct = ""
mysock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
mysock.connect(('192.192.4.2',3000))
except socket.error:
sys.exit("Connect failed")
MsgList =[150, 3, 192, 192, 4, 2, 192, 192, 4, 230, 0, 0, 0, 0, 0, 1, 0, 2, 17, 0, 0, 0, 4, 158]
for num in MsgList:
MsgStruct = MsgStruct + struct.pack('@B',num)
try:
mysock.send(MsgStruct)
except error:
mysock.close()

timeout = 5 #5 second


socklist1,socklist2,socklist3=select.select([mysock],[],[],timeout)
if len(socklist1)!=0:
Msg = socklist1[0].recv( 4096 )
print Msg
else:
print 'not received anything'

mysock.close()

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧