如果recv函数的flags参数设置为MSG_PEEK,则无论len参数是多大,都只能接收第一个包。
比如在发送端先发送"aaa",再发送"bbb",则始终只能接收到"aaa"。
是不是与socket的创建或者connect有关?我没有用WSA***函数,用的都是原始函数。
我的发送端在Unix和Windows下都试过,同样的结果。
有解决问题者不仅奉送100分,另可到下面的帖子拿100分。
http://expert.csdn.net/Expert/topic/1720/1720137.xml?temp=.2730219
16 个解决方案
#1
补充说明,我已经“呼叫”过WSAStartup函数了。
#2
如果recv函数的flags参数设置为MSG_PEEK,则无论len参数是多大,都只能接收第一个包。
try it:
flags = 0;
it do work.
try it:
flags = 0;
it do work.
#3
是你标志位的设置问题.
#4
http://www.csdn.net/develop/read_article.asp?id=16605
#5
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
也就是说,你没有清空recv buffer, 下次的Onrecieved事件是不会有的。
请不要用MSG_PEEK,除非你有一个thread,去清空这个recv的buf,
最好用flag = 0,来忽略。
也就是说,你没有清空recv buffer, 下次的Onrecieved事件是不会有的。
请不要用MSG_PEEK,除非你有一个thread,去清空这个recv的buf,
最好用flag = 0,来忽略。
#6
首先申明我的目的:我只是想从套接口中取出东西看看,不想删除,这正是MSG_PEEK的作用。
其次,两端程序建立连接后的工作过程:
1. 发送者发送"aaa";
2. 发送者发送"bbb";
3. 接收者以peek方式接收,接收到"aaa";
4. 接受者以peek方式接收,接收到"aaa"。
在这里我是故意造成两次接收相同内容这个效果的。
我的问题是:
为什么只能接收到"aaa",无法接收到后面的"bbb"???????????
其次,两端程序建立连接后的工作过程:
1. 发送者发送"aaa";
2. 发送者发送"bbb";
3. 接收者以peek方式接收,接收到"aaa";
4. 接受者以peek方式接收,接收到"aaa"。
在这里我是故意造成两次接收相同内容这个效果的。
我的问题是:
为什么只能接收到"aaa",无法接收到后面的"bbb"???????????
#7
但你总要有一个thread去清空呀
#8
再列举一种情况:
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
4. 接收者以peek方式接收4096字节,收到"67890"。
步骤4只收到了第一次发送的5个字节以后的内容,没收到第二次发送的内容,可见Windows在这里是分包处理。
有没有办法让步骤4接收到第二次发送的内容呢?
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
4. 接收者以peek方式接收4096字节,收到"67890"。
步骤4只收到了第一次发送的5个字节以后的内容,没收到第二次发送的内容,可见Windows在这里是分包处理。
有没有办法让步骤4接收到第二次发送的内容呢?
#9
peek的时候是取出数据,但是不清空接收缓冲区的
比如收到了50字节的数据
用peek来读出来,那么数据在接受缓冲区里面还是存在的。
如果用正常方式那么就会把你接收的数据从接收缓冲区里面去掉了
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
lyghe(TComponent* AOwner) 的情况是这样的
再列举一种情况:
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
这个时候原来接收缓冲区里面的数据"1234567890"已经变成了"67890";所以下面再接收一定是从6开始的,如果在这一步用peek方式接收的话,那么接收缓冲区的数据还是"1234567890",下面再接收的话还能读出来相同的内容("1234567890")。
4. 接收者以peek方式接收4096字节,收到"67890"。
比如收到了50字节的数据
用peek来读出来,那么数据在接受缓冲区里面还是存在的。
如果用正常方式那么就会把你接收的数据从接收缓冲区里面去掉了
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
lyghe(TComponent* AOwner) 的情况是这样的
再列举一种情况:
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
这个时候原来接收缓冲区里面的数据"1234567890"已经变成了"67890";所以下面再接收一定是从6开始的,如果在这一步用peek方式接收的话,那么接收缓冲区的数据还是"1234567890",下面再接收的话还能读出来相同的内容("1234567890")。
4. 接收者以peek方式接收4096字节,收到"67890"。
#10
我受不了了!!!!!
你们说的道理我都明白!
我的问题是既然发送者连续发送了"1234567890"和"abcdefg",为什么peek方式的接收者接收到的只有"1234567890"的内容?为什么后面没有跟上"abcdefg"?
你们说的道理我都明白!
我的问题是既然发送者连续发送了"1234567890"和"abcdefg",为什么peek方式的接收者接收到的只有"1234567890"的内容?为什么后面没有跟上"abcdefg"?
#11
我反复作了实验,只要接收者不把缓冲区中的第一次发送的内容取走,哪怕只剩一个字节在缓冲区中,peek方式都无法读取以后发送的内容。
#12
你真的明白?
#13
peek是什么意思,它只是偷看,查看的意思,就是说你如果不清缓存的话,后面的包内容是peek不到的,除非有PEEK_ALL一样的参数。
#14
你们这么说我倒不明白了,同样的程序在Unix上很正常,在Win上面反而不行。
你们的意思是不是说Windows处理TCP包时是一个一个处理的?前面一个包不处理完就不处理后面的?为什么recv函数不用peek方式能够一次全取出来而用peek就不行?两种方式的内核处理方法不同吗?Microsoft为什么这么傻呢?
你们的意思是不是说Windows处理TCP包时是一个一个处理的?前面一个包不处理完就不处理后面的?为什么recv函数不用peek方式能够一次全取出来而用peek就不行?两种方式的内核处理方法不同吗?Microsoft为什么这么傻呢?
#15
痛苦啊
#16
把flag设置为0看看!!
#1
补充说明,我已经“呼叫”过WSAStartup函数了。
#2
如果recv函数的flags参数设置为MSG_PEEK,则无论len参数是多大,都只能接收第一个包。
try it:
flags = 0;
it do work.
try it:
flags = 0;
it do work.
#3
是你标志位的设置问题.
#4
http://www.csdn.net/develop/read_article.asp?id=16605
#5
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
也就是说,你没有清空recv buffer, 下次的Onrecieved事件是不会有的。
请不要用MSG_PEEK,除非你有一个thread,去清空这个recv的buf,
最好用flag = 0,来忽略。
也就是说,你没有清空recv buffer, 下次的Onrecieved事件是不会有的。
请不要用MSG_PEEK,除非你有一个thread,去清空这个recv的buf,
最好用flag = 0,来忽略。
#6
首先申明我的目的:我只是想从套接口中取出东西看看,不想删除,这正是MSG_PEEK的作用。
其次,两端程序建立连接后的工作过程:
1. 发送者发送"aaa";
2. 发送者发送"bbb";
3. 接收者以peek方式接收,接收到"aaa";
4. 接受者以peek方式接收,接收到"aaa"。
在这里我是故意造成两次接收相同内容这个效果的。
我的问题是:
为什么只能接收到"aaa",无法接收到后面的"bbb"???????????
其次,两端程序建立连接后的工作过程:
1. 发送者发送"aaa";
2. 发送者发送"bbb";
3. 接收者以peek方式接收,接收到"aaa";
4. 接受者以peek方式接收,接收到"aaa"。
在这里我是故意造成两次接收相同内容这个效果的。
我的问题是:
为什么只能接收到"aaa",无法接收到后面的"bbb"???????????
#7
但你总要有一个thread去清空呀
#8
再列举一种情况:
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
4. 接收者以peek方式接收4096字节,收到"67890"。
步骤4只收到了第一次发送的5个字节以后的内容,没收到第二次发送的内容,可见Windows在这里是分包处理。
有没有办法让步骤4接收到第二次发送的内容呢?
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
4. 接收者以peek方式接收4096字节,收到"67890"。
步骤4只收到了第一次发送的5个字节以后的内容,没收到第二次发送的内容,可见Windows在这里是分包处理。
有没有办法让步骤4接收到第二次发送的内容呢?
#9
peek的时候是取出数据,但是不清空接收缓冲区的
比如收到了50字节的数据
用peek来读出来,那么数据在接受缓冲区里面还是存在的。
如果用正常方式那么就会把你接收的数据从接收缓冲区里面去掉了
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
lyghe(TComponent* AOwner) 的情况是这样的
再列举一种情况:
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
这个时候原来接收缓冲区里面的数据"1234567890"已经变成了"67890";所以下面再接收一定是从6开始的,如果在这一步用peek方式接收的话,那么接收缓冲区的数据还是"1234567890",下面再接收的话还能读出来相同的内容("1234567890")。
4. 接收者以peek方式接收4096字节,收到"67890"。
比如收到了50字节的数据
用peek来读出来,那么数据在接受缓冲区里面还是存在的。
如果用正常方式那么就会把你接收的数据从接收缓冲区里面去掉了
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
lyghe(TComponent* AOwner) 的情况是这样的
再列举一种情况:
1. 发送者发送"1234567890"
2. 发送者发送"abcdefg"
3. 接收者不用peek而直接接收5个字节,收到"12345";
这个时候原来接收缓冲区里面的数据"1234567890"已经变成了"67890";所以下面再接收一定是从6开始的,如果在这一步用peek方式接收的话,那么接收缓冲区的数据还是"1234567890",下面再接收的话还能读出来相同的内容("1234567890")。
4. 接收者以peek方式接收4096字节,收到"67890"。
#10
我受不了了!!!!!
你们说的道理我都明白!
我的问题是既然发送者连续发送了"1234567890"和"abcdefg",为什么peek方式的接收者接收到的只有"1234567890"的内容?为什么后面没有跟上"abcdefg"?
你们说的道理我都明白!
我的问题是既然发送者连续发送了"1234567890"和"abcdefg",为什么peek方式的接收者接收到的只有"1234567890"的内容?为什么后面没有跟上"abcdefg"?
#11
我反复作了实验,只要接收者不把缓冲区中的第一次发送的内容取走,哪怕只剩一个字节在缓冲区中,peek方式都无法读取以后发送的内容。
#12
你真的明白?
#13
peek是什么意思,它只是偷看,查看的意思,就是说你如果不清缓存的话,后面的包内容是peek不到的,除非有PEEK_ALL一样的参数。
#14
你们这么说我倒不明白了,同样的程序在Unix上很正常,在Win上面反而不行。
你们的意思是不是说Windows处理TCP包时是一个一个处理的?前面一个包不处理完就不处理后面的?为什么recv函数不用peek方式能够一次全取出来而用peek就不行?两种方式的内核处理方法不同吗?Microsoft为什么这么傻呢?
你们的意思是不是说Windows处理TCP包时是一个一个处理的?前面一个包不处理完就不处理后面的?为什么recv函数不用peek方式能够一次全取出来而用peek就不行?两种方式的内核处理方法不同吗?Microsoft为什么这么傻呢?
#15
痛苦啊
#16
把flag设置为0看看!!