我目前正在开发一个客户端 - 服务器应用程序。服务器渲染图像,使用Nvidias H264编码器压缩它们并将它们发送到客户端。在客户端,图像被解压缩并显示。我使用TCP和UDP Berkeley Windows套接字的包装器。 UDP工作正常,所有图片都正常显示。切换到TCP传输时,会出现一些随机失真。不是一直以来,只是在某些场合。失败通常如下所示:
http://de.tinypic.com/r/14sedf6/8
它可以保持约5到10帧(60fps)。网站 http://www.onsip.com/about-voip/sip/udp-versus-tcp-for-voip表示,使用TCP进行音频传输会导致某种抖动,这对于最终用户来说是“不可接受的”。。您是否认为抖动是导致观察到的图像失真或其他任何线索的原因?
这是TCP包装器的代码。像Bind()这样的函数在超类中实现并且应该可以工作,因为udp包装器也使用它们。 :)
TcpSocket::TcpSocket()
{
WSADATA wsaData;
int i = WSAStartup(MAKEWORD(2,2), &wsaData);
m_Sock = -1;
}
bool TcpSocket::Create()
{
if ((m_Sock = socket(AF_INET, SOCK_STREAM, 0)) > 0)
return true;
return false;
}
bool TcpSocket::Listen(int que)
{
if (listen(m_Sock, que) == 0)
return true;
return false;
}
bool TcpSocket::Accept(TcpSocket &clientSock)
{
int size = sizeof(struct sockaddr);
clientSock.m_Sock = accept(m_Sock,
(struct sockaddr *) &clientSock.m_SockAddr, (socklen_t *) &size);
if (clientSock.m_Sock == -1)
cout << "accept failed: " << WSAGetLastError() << endl;
WSACleanup();
return false;
return true;
}
bool TcpSocket::Connect(string address, int port)
{
struct in_addr *addr_ptr;
struct hostent *hostPtr;
string add;
try
{
hostPtr = gethostbyname(address.c_str());
if (hostPtr == NULL)
return false;
// the first address in the list of host addresses
addr_ptr = (struct in_addr *) *hostPtr->h_addr_list;
// changed the address format to the Internet address in standard dot notation
add = inet_ntoa(*addr_ptr);
if (add.c_str() == "")
return false;
} catch (int e)
{
return false;
}
struct sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(port);
sockAddr.sin_addr.s_addr = inet_addr(add.c_str());
if (connect(m_Sock, (struct sockaddr *) &sockAddr, sizeof(struct sockaddr))== 0)
return true;
return false;
}
int TcpSocket::Receive(char *buff, int buffLen)
{
return recv(m_Sock, buff, buffLen, 0);
}
int TcpSocket::Send(const char *buff, int len)
{
return send(m_Sock, buff, len, 0);
}
非常感谢您提供任何帮助,线索或建议!
Edit1:我在客户端获取数据包如下:
//This is the TCP read() call which should block until something is received
int i = server->Receive(serverMessage, 100000);
//Passing the received buffer to decoder. sizeof(UINT8) is because of an identifyer which kind of package is received,
//sizeof(int) is the length of the actual buffer
m_decoder->parseData((const unsigned char*)(serverMessage + sizeof(UINT8) + sizeof(int)), size);
答案 0 :(得分:0)
正如您链接的VOIP页面所说,UDB和TCP之间唯一的差异,假设其他一切都正确实现,TCP会偶尔延迟您的数据。所以真正的问题是:输入数据的延迟会导致你的H264解码器像你的图像一样以紫色画出一半的屏幕吗?我不太了解这个解码器来回答这个问题。
更多地解释这种偶然延迟的来源:网络不时丢弃数据包。可能是因为链路过载,或是因为电噪声或宇宙射线;类似的东西。
因此,当使用UDP并丢弃数据包时,数据流丢失了一些数据;你的H264解码器将它拒绝为腐败,1/60秒后出现一个新帧,你没有注意到它。
另一方面,TCP被迫以正确的顺序正确地传递每个数据包。因此,当数据包被丢弃时,TCP会稍稍等待,然后重新发送丢失的数据。如果连续两个数据包被丢弃,TCP会使等待时间加倍并再次尝试,依此类推。在问题TCP vs UDP on video stream的答案中查看类似信息