基于udp的网络编程socket的错误10054与SOCKET的发送与接收缓冲区的设置(udp丢包)

哎!长叹一声!今天上班很鬼火,被老板骂了一顿,严重的打击了我的自信!哎,鬼火啊,到今天下班以前,才把任务完成了一点点。明天要继续努力哦!总结今天碰到的问题。
首先:今天在做一个视频转发器,用vlc播放器推视频流,通过转发器然后发送到另外一个pc,然后用vlc播放器播放,这些都是基于udp的socket的。
在基于udp的socket的发送数据是,碰到了主要两个问题。

1、关于UDP socket 的10054错误

                        FD_ZERO(&rfd); // 在使用之前总是要清空  
			FD_ZERO(&wfd);
			// 开始使用select  
			FD_SET(PrimaryUDP, &rfd); // 把PrimaryUDP(socket)放入要测试的描述符集中  
			 
			
			int maxfdp=PrimaryUDP>PrimaryUDP1?PrimaryUDP+1:PrimaryUDP1+1;
			int nRet = select(maxfdp, &rfd, 0, NULL, &timeout);// 检测是否有套接口是否可读  
                        //nRet返回的-1,所以这出现问题了,经过WSAGetLastError()返回的是10054

		//	if (nRet == SOCKET_ERROR)     
		//	{  
		//		printf("select() %d/n",WSAGetLastError());  
		//		return 1;  
		//	}  
		//	else if (nRet == 0) // 超时  
		//	{  
		//		printf("timeout/n");  
		//		closesocket(PrimaryUDP);  
		//		closesocket(PrimaryUDP1);  
		//		break;  
		//	}  
int nRet = select(maxfdp, &rfd, 0, NULL, &timeout);// 检测是否有套接口是否可读  
                        //nRet返回的-1,所以这出现问题了,经过WSAGetLastError()返回的是10054
经过查证: 网上说的是winsock自已的bug。在初始化SOCKET时加上底下这段代码,就可以解决以上的问题。
DWORD dwBytesReturned=0;
		BOOL bNewBehavior=FALSE;
		DWORD status;
		status = WSAIoctl(PrimaryUDP, SIO_UDP_CONNRESET,
			&bNewBehavior, sizeof(bNewBehavior),
			NULL, 0, &dwBytesReturned,
			NULL, NULL);
		if (SOCKET_ERROR == status)
		{
			DWORD dwErr = WSAGetLastError();
			if (WSAEWOULDBLOCK == dwErr)
			{
				// nothing to do
				return(FALSE);
			}
			else
			{
				printf("WSAIoctl(SIO_UDP_CONNRESET) Error: %d\\n", dwErr);
				return(FALSE);
			}
		}
2、 SOCKET的发送与接收缓冲区

在我用vlc播放器不断地向转发器发送udp数据包时,经过转发器转发数据,可是在这里出现了一个问题,就是视频流的udp数据包丢失很严重,使的在另外一台电脑的vlc播放器播放视频的时候都是花的,抓取数据包,丢了很多数据包。udp数据包在局域网都丢了这么多数据包,肯定不正常。
减少丢包方法: 1:设置缓冲! 2:使用线程池。
所以我我设置SOCKET的发送与接收缓冲区,经过设置以后,丢包的情况就改善很好了,视频能够正常的播放了。
设置方法为:
                 int optVal = 32*1024 ;
int optLen = sizeof(int);
setsockopt(PrimaryUDP,SOL_SOCKET,SO_RCVBUF,(char*)&optVal,optLen);
这个是这事socket PrimaryUDP的接受缓冲区为32*1024,即32K
//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));



参考文献:

http://blog.csdn.net/wesleyluo/article/details/6149071
http://blog.csdn.net/ccnucjp8136/article/details/4515002





你可能感兴趣的:(c++)