套接字调用recvfrom似乎陷入了无限循环

时间:2016-02-24 22:16:35

标签: python-2.7 sockets

我从一位同事那里继承了一段代码,我需要整理并转化为一些内部知识产权。

我的问题是读取套接字。我调试了代码,我可以看到套接字已正确打开。一切运行正常,直到解释器运行以下代码行

    data, addr = any_struct.recv_socket.recvfrom(2048)

解释器疯了,我必须通过任务管理器杀死python来阻止它。我已尝试使用调试程序逐步执行代码,但它无法进入recvform调用。

我在将这些代码转化为有价值的东西的早期阶段。有关如何调试/修复此问题的任何建议?当我发现问题所在时,我确定自己会踢,但目前没有灯泡。

之前我使用过套接字,但很久以前就用过C语言,甚至不是C ++

1 个答案:

答案 0 :(得分:0)

正如@nos在评论中已经提到的那样,如果没有数据要接收,那么通常会阻止调用直到有数据要返回。但是,你坐在那里等待输入的应用程序不符合解释器“疯狂”的任何合理定义,所以我认为情况并非如此。

有三种可能性让人想起。一个是套接字在创建时设置为非阻塞 - 检查使用的套接字选项。在这种情况下,当然函数不会阻塞 - 在Python中我相信这是通过适当的错误传达的。

第二种可能性是套接字是面向连接的(例如TCP)并且连接已经关闭 - 这会导致任何recv() - 系列调用在您调用它时立即返回空数据,这通常是如果没有记住这段代码,那么会导致繁忙的循环。

第三种可能性是你的应用程序的某些其他部分(甚至可能是另一个执行线程?)已经关闭了你脚下的套接字而你在无效套接字上调用recvfrom()。我宁愿期望这会立即引发异常。

我建议采取以下步骤:

  1. 确认正在使用的套接字的确切类型 - 如果是面向连接的(例如TCP),那么我建议您使用recv()代替recvfrom()
  2. 添加一些指示recvfrom()的返回码的跟踪。如果无法打印到标准输出,则打开带有追加模式的文件并写入该文件。如果你真的没有办法让调试跟踪进入你的代码,那么调试任何问题都会像滑冰一样上坡我真的建议你解决这个问题。尝试查看logging模块以获得方便的方法(但现在只需转储硬编码的文件名可能会更容易)。
  3. 确保将recvfrom()调用包装在通用try...except中,该通用Exception捕获recvfrom()的所有子类并记录一些跟踪。如果要在不影响代码流的情况下执行此操作,可以随时重新引发它们。
  4. 根据上述结果,您可以选择接下来的步骤。如果解释器在recvfrom()没有返回时“疯狂”,那么这意味着您已经遇到了Python中的一些奇怪的错误或它正在使用的库(异常!);或者你的应用程序中有其他线程导致了这个问题。

    最后一个想法是,如果您使用的是Windows,那么如果您的应用程序未启用,我不确定防火墙是否会导致recvfrom()中的奇怪行为;但我仍然希望这可以表现为奇怪的返回代码或Python中package math.series; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.DoubleStream; import java.util.stream.IntStream; /** * Created by Michael * Creation date 3/6/2016. * @link https://stackoverflow.com/questions/35826081/calculating-ex-in-c-sharp * @link https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80 */ public class TaylorSeries { public static final int DEFAULT_NUM_TERMS = 10; public static void main(String[] args) { int n = 10000000; double y = 1.0; System.out.println(String.format("pi using %d terms", n)); System.out.println(String.format("%20s %20s %20s %20s", "n", "series", "expected", "error")); double expected = Math.PI; double series = TaylorSeries.pi(0.0, n); double error = expected - series; System.out.println(String.format("%20.16f %20.16f %20.16f %20.6e", y, series, expected, error)); n = 50; System.out.println(String.format("exp using %d terms", n)); System.out.println(String.format("%20s %20s %20s %20s", "x", "series", "expected", "error")); for (double x = 0.0; x <= 3.0; x += 0.25) { expected = Math.exp(x); series = TaylorSeries.expLambda(x, n); error = expected - series; System.out.println(String.format("%20.16f %20.16f %20.16f %20.6e", x, series, expected, error)); } System.out.println(String.format("sin using %d terms", n)); System.out.println(String.format("%20s %20s %20s %20s", "x", "series", "expected", "error")); for (double x = 0.0; x <= Math.PI; x += Math.PI/20.0) { expected = Math.sin(x); series = TaylorSeries.sinLambda(x, n); error = expected - series; System.out.println(String.format("%20.16f %20.16f %20.16f %20.6e", x, series, expected, error)); } System.out.println(String.format("cos using %d terms", n)); System.out.println(String.format("%20s %20s %20s %20s", "x", "series", "expected", "error")); for (double x = 0.0; x <= Math.PI; x += Math.PI/20.0) { expected = Math.cos(x); series = TaylorSeries.cosLambda(x, n); error = expected - series; System.out.println(String.format("%20.16f %20.16f %20.16f %20.6e", x, series, expected, error)); } } public static double exp(double x, int n) { double sum = 1.0; double term = 1.0; for (int i = 1; i <= n; ++i) { term *= x / i; sum += term; } return sum; } public static double pi(double x, int n) { return IntStream.range(0, n) .mapToDouble(i -> 8.0/(4*i+1)/(4*i+3)) .sum(); } /** * A JDK 8 implementation for exp * @param x function argument * @param n terms to include in the series sum * @return exp(x) * @link https://stackoverflow.com/questions/35830072/taylor-series-using-jdk-8-lambdas */ public static double expLambda(double x, int n) { final AtomicInteger i = new AtomicInteger(1); return DoubleStream.iterate( 1.0, term -> term*x/i.getAndIncrement() ).limit(n).sum(); } public static double sinLambda(double x, int n) { final AtomicInteger i = new AtomicInteger(0); return DoubleStream.iterate( 0.0, term -> ((i.get() & 1) == 0 ? 1 : -1)*((i.get() == 0) ? x/i.incrementAndGet() : term*x*x/i.incrementAndGet()/i.incrementAndGet()) ).limit(n).sum(); } public static double cosLambda(double x, int n) { final AtomicInteger i = new AtomicInteger(0); return DoubleStream.iterate( 0.0, term -> ((i.get() & 1) == 0 ? 1 : -1)*((i.get() == 0) ? 1.0/i.incrementAndGet() : term*x*x/i.getAndIncrement()/i.getAndIncrement()) ).limit(n).sum(); } } 的异常。