社区
网络编程
帖子详情
使用TCP,如果客户端发送请求太快,服务端出现接收数据出错的情况
yinzhaohui
2005-06-15 08:28:02
如程序上传文件,如果上传2G的文件分块4K一个进行上传,上传太快出现后面数据出错,上传端上延时不会出错, 为什么,解决方法
...全文
1448
11
打赏
收藏
使用TCP,如果客户端发送请求太快,服务端出现接收数据出错的情况
如程序上传文件,如果上传2G的文件分块4K一个进行上传,上传太快出现后面数据出错,上传端上延时不会出错, 为什么,解决方法
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
11 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
yinzhaohui
2005-06-18
打赏
举报
回复
谢谢大家,我以解决这个问题,是接收端的问题,我的程序会处理拈包问题,所以不会在这个问题上,最后确定SOCKET的接收函数revc使用阻塞方式,要求收1024可是收了640就返回了,
yoqi
2005-06-16
打赏
举报
回复
你是编程思路不对,把流格式的的TCP当成数据包格式的UDP来用了,一般做法是这样(写代码比较直观):
struct packet_t
{
int len;
int cmd;
char data[1];
};
class peer_t
{
....
// 两个缓存区,其中 buffer_t 是自增长
buffer_t m_recvbuffer;
buffer_t m_sendbuffer;
bool is_alive();
void stop();
void on_read();
void on_write()
{
handle_sendbuffer();
}
...
void send_data(void* data, int len)
{
// 都先放到发送缓存区
m_sendbuffer.write(data, len);
handle_sendbuffer();
}
void handle_recvbuffer();
void handle_sendbuffer();
};
peer_t::on_read()
{
char buf[4096];
int recv_len = recv(....buf, sizeof(buf));
if (recv_len > 0)
{
// 不管3721,都接收回缓存区再说,然后从缓存区去数据处理
m_recvbuffer.write(buf, recv_len);
handle_recvbuffer();
} else if ...
}
peer_t::handle_recvbuffer()
{
while (is_alive())
{
char* recv_buf = m_recvbuffer.buffer();
int recv_len = m_recvbuffer.length();
packet_t* packet = (packet_t*) recv_buf;
// 检查是否收够完整的一个包
if (recv_len < 4 /* sizeof(packet_t.len) */) break;
if (packet->len > MAX_PACKET_SIZE)
{
// 太大的包,可能是攻击包,或错误的包,不接受
stop();
break;
}
if (recv_len < 4 + packet->len) break;
// 处理一个包
process_packet(packet);
// 把已处理的包清除出缓存区
m_recvbuffer.descard(4 + packet->len);
}
}
peer_t::handle_sendbuffer()
{
while (is_alive())
{
char* buf_ptr = m_sendbuffer.buffer();
int buf_len = m_sendbuffer.length();
if (buf_len < 1) break;
// 尽量发,能发多少就多少,剩下的下次再发
int send_len = send(...buf_ptr, buf_len);
if (send_len > 0)
{
// 把已发的清除出缓存区
m_sendbuffer.descard(send_len);
} else if ....
}
}
当然如果你是发送文件,一般做法是先发一个包头,然后源源不断的发文件数据,那就是另一个做法了,因为上面的代码是最起码收完一个完整包到缓存区才分析运作,而且限制了最大包头长度。稍为改一下就可以。
yinzhaohui
2005-06-15
打赏
举报
回复
我设置为1k还是不行,有和我相同问题的人吗
jun_01
2005-06-15
打赏
举报
回复
发送端缓冲满了,而导致数据出错吧?
yinzhaohui
2005-06-15
打赏
举报
回复
谢谢大,如何处理这个问题
jebbthe(青苹果)
如果保证 客户端要保证下一次发送数据前,前一次发送的数据已经成功送出
是使用数据报长度+数据报内容 =1K吗?
jebbthe
2005-06-15
打赏
举报
回复
你按顺序发的话是不会有问题的,需要注意几点
1。客户端要保证下一次发送数据前,前一次发送的数据已经成功送出
2。分块不要分得太大,最好控制在1K左右
3。如果必要,可以采用 数据报长度+数据报内容来防止拈包
菲斯可儿
2005-06-15
打赏
举报
回复
4K有些大吧,1K试试。
xxrl
2005-06-15
打赏
举报
回复
我也是有这种情况 采用将数据限制在1K也不行 也是苦恼的不行
younggle
2005-06-15
打赏
举报
回复
处理好粘包问题就不会出错了。
QQ: 84162092
jebbthe
2005-06-15
打赏
举报
回复
1.系统支持的最大的数据报你可以调用GetSockOpt来获得,我说的1K指的就是系统支持的最大的数据报长度。
2.一定得记得判断send的结果,很多粗心的程序员会忽略这点。
3. 确定你的程序到底是发送端有问题还是接收方有问题,我更怀疑是你的接收方可能有bug。
4.还是那个粘包问题,我不知道你的程序机制是怎么样的,会不会有这个问题得由你自己来判断了:)
jun_01
2005-06-15
打赏
举报
回复
除非在局域网,否则连续发送包肯定数据错乱
计算机网络面试题
2、
TCP
是怎么去保证可靠传输的3、
TCP
三次握手4、
TCP
拥塞控制5、CDN的原理是什么6、DNS过程7、为什么
TCP
连接是可靠的8、HTTP
请求
方法9、HTTP首部字段10、https的加密过程以及如何防止中间人攻击11、通过什么机制处理...
使用
netty4.x
客户端
接收较大数据量报文时发生的读取不完整bug修复记录
1、先说问题 背景:服务是运行在Linux上的安全网关...现象:数据量较小时完全可以正常收发报文,当
服务端
发送
的报文数据量较大时(本例是将近600k)概率性
出现
接收数据
直接调用readComplete()方法而没有走channelRead...
计算机网络学习笔记(五):运输层
多次交互:
客户端
程序和
服务端
程序需要多次交互才能实现应用程序的功能接收电子邮件的POP3
发送
电子邮件的SMTP传输文件的FTP数据需要分段传输:应用程序传输的文件需要分段传输浏览器访问网页:网页中图片和HTML文件...
传输层协议之
TCP
TCP
协议是传输控制协议,所谓的传输控制指的是,所有的
发送
本质上是拷贝,我们应用层调用的一切的网络IO接口,其实是把数据拷贝给了传输层,说白了就是操作系统,后续的数据什么时候发,发多少?
出错
了怎么办,完全...
Redis
客户端
与
服务端
交互详解
C/S 两端
使用
的协议数据类型
请求
/响应模式 串行化实现 pipeline实现 事务模式 1、入队/执行分离的事务原子性 2、事务的一致性 3、事务的只读操作 4、乐观锁的可串行化事务隔离 5、事务实现 6、事务交互模式 ....
网络编程
18,363
社区成员
64,187
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章