TCP/IP 传送大数据量问题--有请崔明..

water 2000-01-12 04:50:00
用TCP/IP从数据采集计算机把数据实时传送到用户端计算机做实时处理
采集端每隔15ms将采集的6k数据发送出去,为了测试我做了一个程序,用
VC6.0的CAsyncSocket,采用循环语句连续发送4K数据:
for(int i=1;i<80;i++)
{
send(4k数据);
}
但用户端能收到前7次的数据,请问是何原因?如何解决?
...全文
1125 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
EaStar1110 2000-10-31
  • 打赏
  • 举报
回复
看过maofeng同志的发言我大受启发,我现在也遇到这个问题,通过延时的确可以解决,但是既然是不确定的出现这种问题,那如何延时才能保证效率呢?我用100M的LAN通过计算理论上12.8KByte/ms是基本的,但我每32kByte的数据包延了20ms还存在问题,有没有比延时更好的办法呢?嗨,也不知道微软的NetMeeting 3.0的屏幕是怎么传的,那个数据量可不小啊,它还能保证速度与正确。真是让我灰心啊。呜~~~
maofeng 2000-03-03
  • 打赏
  • 举报
回复
因为TCP协议采用的是存储-转发机制,所以send成功只是写入系统缓冲区成功,并不表示数据已成功的发送给对方,如果连续不断的发送数据包会导致数据来不及通过网络传送给对方,但系统缓冲被填满,这种情况在UNIX操作系统中会产生两种结果:1.阻塞方式下: send会被阻塞,直到系统缓冲区的内容被发送出去,send会继续执行,数据包并不会丢失;2.非阻塞方式下: send立即返回,并产生EWOULDBLOCK错误,捕获这种错误后,应适当延时后,将发送出错的数据包重新发送;或不断发送直至send成功(这种方法不推荐,因为占用太多CPU处理时间),CAsyncSocket的处理方式类似于UNIX下的非阻塞传送方式,单纯增加发送缓冲区大小的方法并不能解决问题。在网络环境下编程,适当的延时是必要的,编过串口通讯的网友可能对此更有体会。
Truman 2000-02-28
  • 打赏
  • 举报
回复
有请崔明是什么意思?
vb的winsock 控件用过吗?
--------cuiming 2000-2-28
kxy 2000-02-24
  • 打赏
  • 举报
回复
?
netmare 2000-02-24
  • 打赏
  • 举报
回复
cottle和xubin_sh说的对.本来在同步的境况下是不会发生这种情况的,如果SNDBUF满了的话,新的send请求会阻塞住的,直到SNDBUF有空间了才执行,BSD Socket和CSocket都是这种情况,CSocket实际就是在OnSend里做的.
CASysncsocket是异步的,调用CASysncsocket::Send后会立即返回,可以进行其他处理,但不表示可以立刻再次Send,如果不管不顾的不停发送,就可能导致SNDBUF溢出.
要用CASysncsocket可以有两种处理方法:
1继续Send,但要判返回值,如果是SNDBUF满了,则在OnSend中重发
2只在OnSend中发送
han_liu 2000-02-24
  • 打赏
  • 举报
回复
Maybe Request/Answer mode better for u
sintony 2000-02-15
  • 打赏
  • 举报
回复
用select语句间隔
例:
ASSERT(m_Socket != NULL);
// returned value will be less than nSize if client cancels the reading
FD_SET fd = {1, m_Socket};
TIMEVAL tv = {10, 0};
if(select(0, NULL, &fd, NULL, &tv) == 0) {
return SOCKET_ERROR;
}
xubin_sh 2000-01-27
  • 打赏
  • 举报
回复
应该生成一个CAsyncSocket的子类,并覆盖其OnSend的虚函数,在此函数中发一个包。
OnSend函数表示:你现在可以发包了。象你原先的代码,会发生客户端溢出(OverFlow)
正确的代码如下:
class CMySocket:public CAsyncSocket
{
//You code here
//...
//...
virtual void OnSend( int nErrorCode ){
static int i(0);
//i用于判断你现在在发第几个包,类似于你for循环中的i
send(buf/*4k数据*/);
i++;//i加1
}
//以上代码没调试过,可能有错
water 2000-01-27
  • 打赏
  • 举报
回复
我用CSocket类解决了问题,但我还是希望用CASysncsocket.
bares 2000-01-19
  • 打赏
  • 举报
回复
如果不考虑可靠性,可以用UDP.
beck 2000-01-15
  • 打赏
  • 举报
回复
why use "我用时钟每隔10ms发送4K数据", just send it if u have data need to send, and if find the error is will blocked then sleep a while to resend

当接受方处理的速度较慢(或则网络传输速度),send方就会发生SNDBUF满的现象
Firing_Sky 2000-01-15
  • 打赏
  • 举报
回复
在TCP的包头里加一个序列号,当接收方收到包时先对序列号进行判断,对于超时的包不做处理,直接丢弃。因为你是一个实时监控系统,这样做时没有问题的,我以前就是这么做的。
water 2000-01-14
  • 打赏
  • 举报
回复
我用时钟每隔10ms发送4K数据,收端虽然都收到了数据,但速度较慢.
320K数据用了几秒钟.另外阻塞现象一般什么时候发生?,Send发送4K的数据
要多长时间?
-----再加100分!
Daio 2000-01-14
  • 打赏
  • 举报
回复
另外可调用
SetSockOpt设置SO_SNDBUF、SO_RCVBUF选项加大发送与接受缓冲区
在OnSend通知里发送
beck 2000-01-13
  • 打赏
  • 举报
回复
如果是这样,应该是SNDBUF满了,实际上send的时候没有成功。你可以判断send
的返回值,然后尝试延时一下再发。
注意send返回的是以写到缓冲中的数据,你重发时要注意只要把上次没发的发出去
就可以了。
water 2000-01-13
  • 打赏
  • 举报
回复
什么叫粘包现象?
我发送时第一次发4k的'a',第2次发4k的'b'....
接受到的数据前7次也为a,b,c,....但只能到'h'
另加延时确实可以解决问题,但要加多少延时呢?
我要在15ms内传送6K数据不能有太多延时.
cottle 2000-01-13
  • 打赏
  • 举报
回复
重载CAsyncSocket类的OnSend函数,在里面发送数据。如下机代码所示:
void CMyAsyncSocket ::OnSend(int nErrorCode)
{
while (m_nBytesSent < m_nBytesBufferSize)
{
int dwBytes;

if ((dwBytes = Send((LPCTSTR)m_sendBuffer + m_nBytesSent,
m_nBytesBufferSize - m_nBytesSent)) == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK) break;
else
{
TCHAR szError[256];
wsprintf(szError, "Server Socket failed to send: %d",
GetLastError());
Close();
AfxMessageBox (szError);
}
}
else
{
m_nBytesSent += dwBytes;
}
}
if (m_nBytesSent == m_nBytesBufferSize)
{
m_nBytesSent = m_nBytesBufferSize = 0;
m_sendBuffer = "";
}
CAsyncSocket::OnSend(nErrorCode);
}
beck 2000-01-12
  • 打赏
  • 举报
回复
如果是两次或几次的数据粘到了一起,好一点的方法应该是加分割符
Firing_Sky 2000-01-12
  • 打赏
  • 举报
回复
TCP/IP协议出现了粘包现象,两次或几次的数据粘到了一起。解决办法是在两次发送之间加一段延时

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧