小弟刚刚接触通信这块,对这块还不懂,所以想请教几个问题:
1、tcp在数据接收时,调用TcpSocket.Receive(buff);方法,是缓冲区满了进行处理,还是接收一条指令就处理?
举例:我设置缓冲区为1K,一条指令为600个字节的情况下,调用TcpSocket.Receive(buff);方法,缓冲区内只有1条指令,还是会将下条指令的一部分也存储在缓冲区内然后处理??因为如果是后面这种情况的话,肯定要将多余的和后面的指令进行合并来处理
另外udp是什么情况? 因为小弟不是计算机专业,也不是通信专业,可以说对通信这块外行,能否推荐本实用的入门书?
希望各位大虾不吝赐教,先行谢过了。
1、tcp在数据接收时,调用TcpSocket.Receive(buff);方法,是缓冲区满了进行处理,还是接收一条指令就处理?
举例:我设置缓冲区为1K,一条指令为600个字节的情况下,调用TcpSocket.Receive(buff);方法,缓冲区内只有1条指令,还是会将下条指令的一部分也存储在缓冲区内然后处理??因为如果是后面这种情况的话,肯定要将多余的和后面的指令进行合并来处理
另外udp是什么情况? 因为小弟不是计算机专业,也不是通信专业,可以说对通信这块外行,能否推荐本实用的入门书?
希望各位大虾不吝赐教,先行谢过了。
解决方案 »
- WinForm程序运行不了
- wince 窗体打开效果的问题
- 请问在代码中如何把datagridviewtextboxcolumn改为datagridviewcomboboxcolumn?
- 怎么读取webBrowser控件里打开网页的HTML代码,急,100分结贴迅速
- sql搜索生日并比对当前日期的问题 msSql C#
- C#2005写的程序怎样在没安装2005的机器上使用
- 怎么通过程序来实现登陆一个网页以后得到他的SessionID
- 我要开始学习C#,想请问先看哪些书籍为好?
- 如何实现像BCB中DataModal的这种连接,再如如何用set , get取Connection的值
- ADO.NET数据库连接问题
- 初学C#的困惑——Visual Studio和.NET Framework的选择
- 如何比较两个IList的ID差别?
udp是无连接的,那么等于缓冲区没每次都是一个包吗??
tcp和udp都为传输层协议。
tcp提供的是面向连接的,可靠的字节流服务,tcp首先必须建立通讯链路。
udp提供的是一个简单的面向数据报的运输层协议,不提供可靠性,它只是把应用程序传给ip层的数据报发送出去,但是并不能保证它们能到达目的地.
udp虽然不安全,但不需要维护链路,可以节省服务器资源。好像udp速度也比较快。
那就是说,读到的数据,肯能不是刚好1个完整的包,是吗?这是tcp情况,还是UDP也是这样?
{
byte[] buf = new byte[5];
byte[] tempBuf;
int count = 0;
string userName = "", msg = ""; Socket newSocket = _tcpl.AcceptSocket(); if (newSocket.Available > 0)//如果有数据则获取
{
//客户端按自己定的格式发送 例如发送"aa 1 4test"
//"aa"为最初识别码, " 1"为用户名, " 4"为后面字串的长度,"test"为请求内容
newSocket.Receive(buf, 0, 5, SocketFlags.None);
msg = Encoding.ASCII.GetString(buf, 0, 5).Trim('\0');//先获取前5位
if (msg.IndexOf("aa") >= 0) //头两位为aa则格式正确继续处理
{
userName = msg.Substring(2, 3);//获取用户名
newSocket.Receive(buf, 0, 5, SocketFlags.None);//继续取后5位
msg = Encoding.ASCII.GetString(buf, 0, 5).Trim('\0');
count = Convert.ToInt32(msg);//得到串的长度 tempBuf = new byte[count];
newSocket.Receive(tempBuf, 0, count, SocketFlags.None);
msg = Encoding.ASCII.GetString(tempBuf, 0, count).Trim('\0');//根据得到的长度获取最后的内容if (msg == "test")
{
//实际操作
}}
}}
将信息发给网络上所有电脑
至于有没有被接收到 就不去管了
tcp 不一样 只有互相之间建立连接才可以通信
电脑怎知道什么叫做“一条指令”?对于tcp,粘包是正常现象,因为tcp(看看rtf文档)就是这样设计的。对于.net所写的服务端,接收缓冲设置为1k未免太小气了,设置为32k也不为过。如果你的服务面向大规模的网络,就好象互联网这样,那么可以考虑短连接而不是长连接方式。如果只是连接树木很有限的一些固定的客户端,则可以考虑长连接方式(因为这样可以直接突破nat限制)。
因为我的包是定义了包头 包长 校验 和包尾的,缓冲区内会不会出现半个包的问题?打比方:缓冲区设置了10个字节,而一个包有4个字节,那么最后面2个字节会不会有内容?也就是说以个包会不会在2次缓冲区内出现??谢谢啦
两种情况(当然是指正常情况下),会导致TcpSocket.Receive方法返回
1. 接收到的数据被读取完了
2. TcpSocket.Receive方法里的buff数组填满了也就是 TcpSocket.Receive 方法接收数据,每次最多只能接收 buff 长度的数据。至于真实接收了多少个字节,就要看 TcpSocket.Receive 方法返回的数值。
打比方:缓冲区设置了10个字节,而一个包有4个字节,那么最后面2个字节会不会有内容?也就是说以个包会不会在2次缓冲区内出现??你所说的缓冲区是什么缓冲区?
不太明白 ,这样说吧TcpClient.Receive里的
buff 字节数组长度是100
^
|
|
系统缓冲区
^
|
|
客户端发送数据这样,你写一个循环如下int len = TcpClient.Receive(buff);
byte[] PackageData = new byte[最在的包大小+buff.Length];
int PackageDataLen = 0; // PackageData数组还有多少的数据
while( len > 0 ) // 说明本次有取到数据,如果长度为0,说明缓冲区里没有数据可以读了
{
//把buff从0开始长度为len的字节复制到PackageData数组从PackageDataLen开始的下标后面(包括PackageDataLen这个下标)
if(判断你的PackageData数组中有没有包含一个完整自定义协议包)
{//有
//取出一个包的数据组成一个包对象,加入到队列
int PkgLen = 刚取走的包所包含的字节数
//把PackageData数组头PkgLen长度的字节全部删除(这步也可以不做,可以采用后面的数据直接覆盖上来)
//然后把从PkgLen下标开始的数据全部移到头部开始的下标处(顺序前移到下标 0 处)
PackageDataLen = PackageDataLen + len - PkgLen // 设置现在PackageData数组里还剩的数据长度
}
else
{
PackageDataLen = PackageDataLen + len;
} // 再从缓存区取数据,
len = TcpClient.Receive(buff);
}
TCP 是建立连接的,按数据发送顺序接收的