现在是一名编码人员 - 既不是新手,也不是专家。现在,我在PPC Linux上的C语言中有一个守护程序。我使用PHP的socket_connect作为客户端在本地连接到此服务。服务器使用epoll通过Unix套接字进行多路复用连接。使用strstr()解析用户提交的字符串中的某些字符/单词,如果找到,则同时向不同的网站生成4个可连接的线程。我使用套接字,连接,写入和读取,通过TCP在每个线程的端口80上与所述web服务器进行交互。所有连接和写入似乎都很成功。然而,读取到Web服务器套接字失败,其中任何一个(A)所有3个线程似乎都挂起,并且只有一个线程返回-1并且errno设置为104.响应线程需要10分钟 - 永恒长:-(。*我在某处读到了104(是EINTR?),它在网络环境中暗示......'连接被对等'重置;或者(B)来自3个线程的0个字节,并且4个线程中只有1个实际返回是不是套接字读/写线程安全?我使用线程安全(和可重入)的libc函数,如strtok_r,gethostbyname_r等。
*我怀疑所说的webhosts实际上正在重置连接,因为当我运行单线程独立(其他一切都相同)时,所有的东西都能正常工作,但当然是串联而不是并行。
还有第二个问题(oops),我无法回写连接到我的epoll-ed Unix套接字的客户端。我的守护程序应用程序将挂起并占用CPU> 100%永远。然而,没有任何东西写给客户端。确保客户端(一个非常典型的PHP套接字应用程序)在发生这种情况时没有关闭连接 - 也没有检测到错误。有什么想法吗?
即使使用Valgrind,GDB或大量日志记录,我也无法弄清楚是什么问题。请尽可能帮助你。
答案 0 :(得分:0)
是的,读/写是线程安全的。但是如果你正在使用它们,请注意gethostbyname()和getservbyname() - 它们返回指向静态数据的指针,并且可能不是线程安全的。
错误104是ECONNREFUSED(不是EINTR)。使用strerror或perror获取特定错误代码的文本错误消息(如“通过对等方重置连接”)。
找出问题的最佳方法是经常进行非常详细的记录 - 记录每个操作的结果,加上连接的IP地址/端口,读/写字节数,线程ID,等等。当然,请确保您的日志记录代码是线程安全的: - )
答案 1 :(得分:0)
10分钟后获取ECONNRESET听起来像是连接超时的结果。 Web服务器没有发送数据,或者您的应用程序没有收到数据。
要测试前者,请将Wireshark等程序连接到本地环回设备,并查找进出端口的流量。
对于后者,请查看epoll()手册页。他们提到使用边缘触发事件可能导致锁定的情况,因为缓冲区中仍有数据,但没有新数据进入,因此不会触发新事件。