UDP分包发送接收问题

走走刀口 2009-11-11 10:37:45
PC机向NOKIA5800XM手机发送大于约510字节的UDP数据时,手机接收不到,所以我只好把数据分包发送,这时问题出现了:

分成每次500字节发送,每次接收到十几个包的时候就阻塞了。

用模似器接收的时候也是这样。如果在服务器向手机分包发送的时候,每次sleep(1),则问题缓解了,但时间一久又会出现这个问题,希望高手帮忙解决下。

我估计是缓冲区的问题,服务器端向手机发送过快,在手机上接收的时候缓冲区满了,其它的部分丢了,接收不到,故阻塞。不知道是否是这样。若是这样的话,有没有清除缓存的方法?
...全文
566 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
走走刀口 2009-11-14
  • 打赏
  • 举报
回复
谢了,看来我只能采用TCP了
走走刀口 2009-11-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 fanyuanwai 的回复:]
重新启动一个线程
[/Quote]

重新启动一个线程的话会导致没接收完成,就进行下一步操作,会引起数据错误。
走走刀口 2009-11-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 designedit 的回复:]
引用楼主 luchao002 的回复:
PC机向NOKIA5800XM手机发送大于约510字节的UDP数据时,手机接收不到,所以我只好把数据分包发送,这时问题出现了:

分成每次500字节发送,每次接收到十几个包的时候就阻塞了。

用模似器接收的时候也是这样。如果在服务器向手机分包发送的时候,每次sleep(1),则问题缓解了,但时间一久又会出现这个问题,希望高手帮忙解决下。

我估计是缓冲区的问题,服务器端向手机发送过快,在手机上接收的时候缓冲区满了,其它的部分丢了,接收不到,故阻塞。不知道是否是这样。若是这样的话,有没有清除缓存的方法?

是的。缓冲区满了后,其它的部分丢了,接收不到,故阻塞。
怎么办?
清除缓冲区的办法是行不通的。因为:服务器端快,手机取用数据慢(取用后还要清除缓冲区[方法是:调用setOffset()与setLength()设置]速度又慢些)还是不行。
使用UDPDatagramConnection时,就允许出现数据丢失这种情况(当出现数据丢失时,程序阻塞--是由你的程序代码写得不好引起的 ),程序不阻塞就行。
若不允许数据丢失,则就使用:SocketConnection。这样服务器端与手机之间会自动进行传输数据速率调整,若服务器端向手机发送过快,则服务器端会自动等待。
[/Quote]

那照你所说的代码写得不好引起的,能给个写是好点的例子吗?
我的代码是:
int j = fileSize / streamSize; // 获取循环次数
int k = fileSize % streamSize; // 获取最后一部分长度
for (int i = 0; i < j; i++) {
dg = conn.newDatagram(streamSize);
conn.receive(dg);
fileArray[i] = dg.getData();
}
if (k != 0) {
int lastSize = fileSize - j * streamSize;
dg = conn.newDatagram(lastSize);
conn.receive(dg);
fileArray[j] = dg.getData();
}
不知道有什么问题,接收是否处理过慢?
凡员外 2009-11-13
  • 打赏
  • 举报
回复
重新启动一个线程
designedIt 2009-11-13
  • 打赏
  • 举报
回复
对于你所说的我能理解,只是我不甘心,发送端发送过快,到客户端这里就注定要丢掉缓存满了后其它的数据吗?
是的。肯定会丢的(UDP没有流量控制)。这就是UDP协议栈的实现特点。
走走刀口 2009-11-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 designedit 的回复:]
引用 6 楼 luchao002 的回复:
那照你所说的代码写得不好引起的,能给个写是好点的例子吗?
我的代码是:
int j = fileSize / streamSize; // 获取循环次数
int k = fileSize % streamSize; // 获取最后一部分长度
for (int i = 0; i < j; i++) {
dg = conn.newDatagram(streamSize);
conn.receive(dg);
fileArray[i] = dg.getData();
}
if (k != 0) {
int lastSize = fileSize - j * streamSize;
dg = conn.newDatagram(lastSize);
conn.receive(dg);
fileArray[j] = dg.getData();
}
不知道有什么问题,接收是否处理过慢?

1,由于是计数循环来控制UDP接收的,只要丢失一个UDP包,就要阻塞了。。。
2,怎么办?
即使楼主所有的UDP包都收到,就一定正确吗?不一定。收到的UDP包会有可能前后次序乱掉的,这些楼主考虑到没有?
3,不知道楼主的程序的真正需求--含义是:UDP对于楼主的真正需求是否合适?(当然了,UDP是手机网络通信中开销最少的)SocketConnection行不行?HttpConnection行不行?UDPConnection主要适合于数据量小(一次就一个UDP包就解决的情况--当然容许数据可以丢失),若大数据要分拆成多个UDP包且不能丢,则并不适合(此时要自己定义双方协议如:每一个UDP包的确认,次序乱了后重新调整等)
4,若一定要采用UDP,且大数据要分拆成多个UDP(其它都无所谓--如:丢失,乱序等),则要避免楼主的情况,则可以:
楼主的网络通信肯定是写在一个工作线程中的(主线程负责手机的UI),可以打开Connector.open(...)中的网络通信超时选项,不丢换UDP包时,通过超时捕获异常来避免阻塞。

[/Quote]

对于你所说的我能理解,只是我不甘心,发送端发送过快,到客户端这里就注定要丢掉缓存满了后其它的数据吗?
designedIt 2009-11-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 luchao002 的回复:]
那照你所说的代码写得不好引起的,能给个写是好点的例子吗?
我的代码是:
int j = fileSize / streamSize; // 获取循环次数
int k = fileSize % streamSize; // 获取最后一部分长度
for (int i = 0; i < j; i++) {
dg = conn.newDatagram(streamSize);
conn.receive(dg);
fileArray[i] = dg.getData();
}
if (k != 0) {
int lastSize = fileSize - j * streamSize;
dg = conn.newDatagram(lastSize);
conn.receive(dg);
fileArray[j] = dg.getData();
}
不知道有什么问题,接收是否处理过慢?
[/Quote]
1,由于是计数循环来控制UDP接收的,只要丢失一个UDP包,就要阻塞了。。。
2,怎么办?
即使楼主所有的UDP包都收到,就一定正确吗?不一定。收到的UDP包会有可能前后次序乱掉的,这些楼主考虑到没有?
3,不知道楼主的程序的真正需求--含义是:UDP对于楼主的真正需求是否合适?(当然了,UDP是手机网络通信中开销最少的)SocketConnection行不行?HttpConnection行不行?UDPConnection主要适合于数据量小(一次就一个UDP包就解决的情况--当然容许数据可以丢失),若大数据要分拆成多个UDP包且不能丢,则并不适合(此时要自己定义双方协议如:每一个UDP包的确认,次序乱了后重新调整等)
4,若一定要采用UDP,且大数据要分拆成多个UDP(其它都无所谓--如:丢失,乱序等),则要避免楼主的情况,则可以:
楼主的网络通信肯定是写在一个工作线程中的(主线程负责手机的UI),可以打开Connector.open(...)中的网络通信超时选项,不丢换UDP包时,通过超时捕获异常来避免阻塞。
designedIt 2009-11-12
  • 打赏
  • 举报
回复
[Quote=引用楼主 luchao002 的回复:]
PC机向NOKIA5800XM手机发送大于约510字节的UDP数据时,手机接收不到,所以我只好把数据分包发送,这时问题出现了:

分成每次500字节发送,每次接收到十几个包的时候就阻塞了。

用模似器接收的时候也是这样。如果在服务器向手机分包发送的时候,每次sleep(1),则问题缓解了,但时间一久又会出现这个问题,希望高手帮忙解决下。

我估计是缓冲区的问题,服务器端向手机发送过快,在手机上接收的时候缓冲区满了,其它的部分丢了,接收不到,故阻塞。不知道是否是这样。若是这样的话,有没有清除缓存的方法?
[/Quote]
是的。缓冲区满了后,其它的部分丢了,接收不到,故阻塞。
怎么办?
清除缓冲区的办法是行不通的。因为:服务器端快,手机取用数据慢(取用后还要清除缓冲区[方法是:调用setOffset()与setLength()设置]速度又慢些)还是不行。
使用UDPDatagramConnection时,就允许出现数据丢失这种情况(当出现数据丢失时,程序阻塞--是由你的程序代码写得不好引起的 ),程序不阻塞就行。
若不允许数据丢失,则就使用:SocketConnection。这样服务器端与手机之间会自动进行传输数据速率调整,若服务器端向手机发送过快,则服务器端会自动等待。
走走刀口 2009-11-11
  • 打赏
  • 举报
回复
请高手指教。

13,100

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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