他们固定在VMware Fusion 8.5.7!见https://communities.vmware.com/thread/544049
我真的不能提供你一个答案,现在和我有什么要说的是比注释长了一点,但我遇到了在VMware Fusion中的类似问题临8.5 10.12与Python的urllib2的。它与urllib2无关。
我开始在传输会话随机接受这个问题,一些Wireshark的调试之后,决定了它是由于TCP窗口上的接收器达到0。出于某种原因,它不会再更新。
如果你不知道TCP窗口是什么,它基本上是接收缓冲区的一个TCP连接的一端的大小。该缓冲区应该扩张和收缩是正常传输时的拥塞控制机制,但不应该发生的事情越来越停留在0
您的会话的转移工作,小于10K的原因窗口是因为默认的TCP窗口通常大约8k。任何比这更少的东西都不会填满接收缓冲区。再者,你基本上希望你处理数据的速度比你接收数据的速度快。
要在我的本地机器上重现此问题,请使用cc client.c -o client
和cc server.c -o server
编译的两个[特别]编写的C程序。运行虚拟机中的客户端和本地计算机上的服务器。
server.c:
/* server.c */
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[1024];
struct sockaddr_in serv_addr, cli_addr;
int n, total;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
memset(buffer, '0xAB', sizeof(buffer));
total = 0;
for (;;) {
n = write(newsockfd, buffer, sizeof(buffer));
if (n < 0)
error("ERROR writing to socket");
else
total += n;
printf("wrote %d/%d\n", n, total);
}
close(newsockfd);
close(sockfd);
return 0;
}
client.c:
/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
fd_set set;
int sockfd, portno, n, total, rv;
struct sockaddr_in serv_addr;
struct hostent *server;
struct timeval timeout;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
bzero(buffer, 256);
FD_ZERO(&set);
FD_SET(sockfd, &set);
sleep(1);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
total = 0;
for (;;) {
rv = select(sockfd + 1, &set, NULL, NULL, &timeout);
if (rv == -1) {
perror("select\n");
} else if(rv == 0) {
printf("timeout\n");
break;
} else {
n = read(sockfd, buffer, 256);
if (n < 0)
error("ERROR reading from socket");
total += n;
printf("read %d/%d\n", n, total);
}
}
close(sockfd);
return 0;
}
这些程序都是直接取自http://www.linuxhowtos.org/C_C++/socket.htm与修改报告更多统计和强制执行停顿了。
这里是Wireshark的演示TCP窗口减少到0和粘贴截图:
我目前的理论是,有在对VMware的侧网络堆栈某种错误的客户,但很难说。到目前为止,我尝试过使用三种不同的虚拟网络接口(e1000,e1000e,vlance),并且每个接口都有相同的问题。
我将尝试尝试各种vmx选项以减少问题发生的可能性,但这显然是稳定系统的杀手,我的用例(虚拟化Jenkins奴隶for CI)根本不允许这种错误。
如果我能学到新东西,我会报告回来。
编辑:我张贴的错误在VMware社区板:再次https://communities.vmware.com/message/2648727
编辑:他们固定在VMware Fusion 8.5.7!请参阅上述链接。
你有没有尝试删除'超时= 10',看看请求的URL是否在默认的超时时间内处理? – Eduard
@EduardDaduya。如果我删除超时,线程将永久卡住。 –
我的歉意,我误解了手边的问题,您正在通过urlopen成功检索数据,但读取检索到的数据引发了上述异常。我还没遇到的东西。我相信这个解释会帮助你解决你目前的问题http://stackoverflow.com/a/26765074/1809168 – Eduard