asp.net用socket发送自定义报文,包括报文头长度,报文头,报文体长度,报文体。对如何发送和接收搞不好了,还请大家帮看看,谢谢

时间:2023-01-11 17:26:25
如题
服务器端

int port = 6000;
            string host = "127.0.0.1";

            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);

            Socket sSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sSocket.Bind(ipe);
            sSocket.Listen(0);
            Console.WriteLine("监听已经打开,请等待");

            //receive message接收
            Socket serverSocket = sSocket.Accept();
            Console.WriteLine("连接已经建立");
            string recStr = "";
            byte[] recByte = new byte[4096];
            int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
            recStr += Encoding.ASCII.GetString(recByte, 0, bytes);//接收报文
//接收报文长度的感觉意思代码如下行
//要求发过来的长度是2字节二进制格式
int sh2 = System.BitConverter.ToInt16(recByte, 0);
//这是字节转int,但好像不是二进制的字节转的呀?
//执行得到不是想要的,只是个意思


            //send message发送
            Console.WriteLine("服务器端获得信息:{0}", recStr);

// recStr接收到的
//想要把接收到的报文,包括报文头长度,报文头,报文体长度,报文体原封不动再发回客户端
            string sendStr =  recStr;
            byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
            serverSocket.Send(sendByte, sendByte.Length, 0);
            serverSocket.Close();
            sSocket.Close();


客户端

int port = 6000;
            string host = "127.0.0.1";//服务器端ip地址

            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);

            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(ipe);

//报文头长度和报文头内容
string _header = "{"mode":"0"}";//报文头内容,拼接json格式,mode为0报文 不加密,为1报文 加密
        short _len = (short)_header.Length;//报文头长度

            //send message发送
//报文头长度要求为2字节二进制格式,这里主要是我不会的了
byte[] bslen = new byte[2];//定义2字节
            bslen = BitConverter.GetBytes(_len);//二进制格式,这里也是意思,这样好像不是二进制
或这样
// bslen = Encoding.GetEncoding(936).GetBytes(Convert.ToString(_len, 2));//感觉这样是二进制了

//报文体
string bodyTpl =
                @"
                <Root>
                    <Head>
                        <Trxcode>{0}</Trxcode>
                        <count>{1}</count>
                    </Head>
                </Root>";
        string Trxcode = "中文";//交易代码
        string count = "您好";//记录数量
        string body = string.Format(bodyTpl, Trxcode, count);

//报文体长度
short _len2t = (short)body .Length;//报文头长度
//报文体长度要求为2字节二进制格式,这里主要是我不会的了
byte[] bslen2t = new byte[2];//定义2字节
            bslen2t = BitConverter.GetBytes(_len2t);//二进制格式,这里也是意思,这样好像不是二进制
或这样
// bslen = Encoding.GetEncoding(936).GetBytes(Convert.ToString(_len2t, 2));//感觉这样是二进制了

           byte[] bsheader = Encoding.ASCII.GetBytes(_header);
 
            byte[] bsbody = Encoding.ASCII.GetBytes(body);
            
//这里是分开发送的,这样对吗?服务器端如何接收,这又是我不会的了
clientSocket.Send(bslen);
            clientSocket.Send(bsheader);

clientSocket.Send(bslen2t);
            clientSocket.Send(bsbody);

//或者合在一起发
//byte[] zh = Encoding.GetEncoding(936).GetBytes(Convert.ToString(_len, 2) + _header +Convert.ToString(_len2t, 2) + body);
// clientSocket.Send(zh);
//但这样不能用BitConverter.GetBytes(_len)这样了,总之就是倒底如何长度是2字节二进制格式
//还有就是如果长度不用2字节二进制格式,就是一个数值,那要如何发送,是分开发?还是合在一起发,搞晕了
//接收时,合在一起发的就截取,但是以字符串还是byte[],有区别吗,以byte[]怎以截取?
//分开发的,又怎么分开接收呢?

            //receive message接收。客户端发出后,服务器端再原封不动发回来接收
            string recStr = "";
            byte[] recBytes = new byte[4096];
            int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
            recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
            Console.WriteLine(recStr);

            clientSocket.Close();

上述服务器端和客户端建立通信,在互相发送一次信息后通信便结束,这个没有关系的

我的问题:
一,发送自定义报文,包括报文头长度,报文头,报文体长度,报文体。要怎么发送?一般发送一段字符串,就是字符串转byte[]后直接发了,但有长度,有头,有体是怎么发,就是没理解了。是分开发,还是合一起发?合一起长度怎么表示,主要是长度是2字节二进制格式。(随便问下,长度就是正常的数值,会有发送的上区别吗)。还请给出代码,最好是2字节二进制格式和就数值 两种,谢谢

二,正常发送后,怎么接收?我的代码只用了
byte[] recByte = new byte[4096];
            int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
            recStr += Encoding.ASCII.GetString(recByte, 0, bytes);//接收报文
这是统一接收了吧?那要怎么区分长度,头和体呢?
网上有说先取前两个字节,看看长度,就确定了后面头和体截取多长了?但我就不会怎么先取前两个字节呢?还请给出代码,谢谢

三,客户端是分开发,还是合一起发?
如分开
clientSocket.Send(bslen);
            clientSocket.Send(bsheader);
合一起发
//byte[] zh = Encoding.GetEncoding(936).GetBytes(Convert.ToString(_len, 2) + _header +Convert.ToString(_len2t, 2) + body);
// clientSocket.Send(zh);
这有什么样的区别?应当用那种呢?

4,合一起发的话,长度是2字节二进制格式和头与体怎么在一起表示啊?还请给出代码,谢谢

5,分开发的话,我发现我的服务器端只接收了两次,如
clientSocket.Send(bslen);//收到
            clientSocket.Send(bsheader);//收到

clientSocket.Send(bslen2t);//没收到了
            clientSocket.Send(bsbody);//没收到了
这应当是我服务器端写的不对造成的,但请能讲讲原理吗?谢谢

6,如用BitConverter.GetBytes(_len)这样发对的,我长度如102,但接收后变为f了
recStr += Encoding.GetEncoding(936).GetString(recByte, 0, bytes);//这样接的

如用// bslen = Encoding.GetEncoding(936).GetBytes(Convert.ToString(_len2t, 2));接到1100110这个一共7位表示102的字符串
这要怎么解决呢,还请给出两种情况的代码,谢谢

汇总
长度2字节二进制格式与头,体怎么发送?
怎么接收时先取前2字节得到长度,2字节二进制格式与数值有区别吗
完整的自定义报文,长度,头,体,怎么发送,分开发?还是合一起发?
分开或合一起发后,怎么相应的接收?

总之就是一个自定义报文,有长度,头,体。长度想要2字节二进制格式,怎么发送和接收?发送是怎么前2字节是长度结合头与体?接收是怎么先取前2字节得到长度,再取到头和体?

还请给出代码,谢谢

16 个解决方案

#1


随便你怎么发,一起发也行分几次发都行。对于这种自定义协议的报文,可以先收2个长度字节,然后根据得到长度再去收后续字节,有多段就以此类推

#2


 不知道你做网站为什么要这种需求。
 监听和接收都需要不停调用,要不然下次有人连你,你就连不上了。
 用多线程来搞。

如果你要区别着发,就要做个标识,要不然收到后你也没办法知道是头还是体。
一次性发也是需要做手脚来标示。

再不则我感觉最好做的就是把对像直接发过来,反正你全是字符,都是简单的类型。
直接弄成对象 序列化发过来 收到再反序列化就行了。

我是这样觉得。

#3


引用 1 楼 xdashewan 的回复:
随便你怎么发,一起发也行分几次发都行。对于这种自定义协议的报文,可以先收2个长度字节,然后根据得到长度再去收后续字节,有多段就以此类推


没太明白您说的,如果分几次发,第一次接收是长度,然后怎么接第二次后续字节呢?
请问能给个代码吗?谢了

还有就是我发了如三次,一长度,二头,三体,这三个是一个数据的总共。我再发一个数据的总共,接收时怎么判断是新的一个数据了呢??

#4


引用 3 楼 shjsmhkd 的回复:
还有就是我发了如三次,一长度,二头,三体,这三个是一个数据的总共。我再发一个数据的总共,接收时怎么判断是新的一个数据了呢??

socket这个东西不是你发几次就一定要收几次的,你可以发N次,但只要你接受的buff足够大,完全可以一行就收完,所以无需去在于收发次数。第一次收2个长度字节,然后解析得到后续还有多少数据需要接收,然后去收这点长度的数据,反复收,每收一次计算剩余长度,直到长度吻合未知。然后再接受2个长度字节,重复上述操作

#5


引用 2 楼 hiose89 的回复:
 不知道你做网站为什么要这种需求。
 监听和接收都需要不停调用,要不然下次有人连你,你就连不上了。
 用多线程来搞。

如果你要区别着发,就要做个标识,要不然收到后你也没办法知道是头还是体。
一次性发也是需要做手脚来标示。

再不则我感觉最好做的就是把对像直接发过来,反正你全是字符,都是简单的类型。
直接弄成对象 序列化发过来 收到再反序列化就行了。

我是这样觉得。


请问怎么做个标识,又怎么根据标识区分,主要是区分多段数据时,一段数据包括长度,头,体,多段时如何判断?
最好有几条代码,谢谢

#6


引用 5 楼 shjsmhkd 的回复:
Quote: 引用 2 楼 hiose89 的回复:

 不知道你做网站为什么要这种需求。
 监听和接收都需要不停调用,要不然下次有人连你,你就连不上了。
 用多线程来搞。

如果你要区别着发,就要做个标识,要不然收到后你也没办法知道是头还是体。
一次性发也是需要做手脚来标示。

再不则我感觉最好做的就是把对像直接发过来,反正你全是字符,都是简单的类型。
直接弄成对象 序列化发过来 收到再反序列化就行了。

我是这样觉得。


请问怎么做个标识,又怎么根据标识区分,主要是区分多段数据时,一段数据包括长度,头,体,多段时如何判断?
最好有几条代码,谢谢


标示这种东西任何方法都可以实现,你可以自己加一些特殊字符来区分,也有更简单来的做法。
比如JSON 就是KEY VALUES的格式。你现在的光有VALUES 所以你不知道哪一个是头哪一个是体,
当你给相应的值 加上标示键后就可以区分了啊。

接收后反序列化一下就成对象了。 

#7


还想请问大家个事,就是socket我用的是个asapx页面,不是一个应用程序

#8


还想请问大家个事,就是socket我用的是个asapx页面,不是一个应用程序,如果服务器那边是分开发的,比如发了三次,那我的一个aspx页面怎么接收三次呢,我试了下,只能接一次啊。

这个大家方便给个代码吗?谢了

#9


aspx只能发 不能收....

收的叫"服务端" 应该是一个exe 或者一个服务..而不是"网页"

#10


引用 9 楼 diaodiaop 的回复:
aspx只能发 不能收....

收的叫"服务端" 应该是一个exe 或者一个服务..而不是"网页"


aspx是能收的,我测试通过,就是aspx发多次时,服务器端返回多次,可aspx只接收一次,想请问有什么方法,aspx也可以接收多次??

#11


引用 10 楼 shjsmhkd 的回复:
aspx是能收的,我测试通过,就是aspx发多次时,服务器端返回多次,可aspx只接收一次,想请问有什么方法,aspx也可以接收多次??

web和服务器多次通信,要么轮询要么websocket

#12


哎,.

你既然都玩socket了. 你就应该知道 socket跟http(asp.net)有什么区别,

asp.net(web) 中是不能随便收发tcp/ip的...

因为他是长连接..http是短连接...这最起码的 你应该懂吧..(如果这你不懂那你没有继续看下去的必要了)

首先我们不说你具体协议如何..反正也没人看..只说流程.

你无非是想通过asp.net后台发送 socket 到"服务端(虽然我不知道你的服务端是不是也是"网页")".然后根据服务端的返回值做处理

明确的告诉你,那是不行的...

因为http在请求之后就没了...所以这个时候 你服务端可能还没有send 但是这个时候 tcpclient已经释放了 根本保持不了..

就算服务端在收到数据马上send 这个时候 也不一定能发过来..更何况这样做根本没意义..这根本就是"短链接"干的事.

长连接是无论何时的 都可以进行收发,否则他的存在也没有意义啊...更何况真正的项目中 这些东西都是异步的...

既然说到"无论何时" 那么显然 http是办不到的...

所以现在你就研究协议报文这种东西 对你来说 还是太早了..因为你连基本的"流程" 可能都不太清楚.

更何况你还让大家直接给你写出代码.....

#13


aspx 基本上是处理浏览器请求时使用,asp.net (以及 IIS)其实经常会重启你的 asp.net 应用程序的另一个进程,来解决许多问题。所以 asp.net 进程经常结束,各种内存中的状态数据经常丢失,你的程序的相关内容也会丢失。

从你的问题中的代码来看,你的“服务器端”Accept 一次,然后 Receive 一次,然后不管是不是分包的部分信息,都把这个当作完整的字符串(仅仅是字符串)执行 Console.WriteLine 输出,然后 Send 一个信息,然后就关闭服务。从这个来看,基本上是一些专门摆着让你了解一些基本语法的小例子上的代码。正常的服务流程根本不是这样的。正常的服务可以 BeginAccept/Accept 上万、几十万的请求,然后获得请求之后每一个单独的信道可以单独进行 BeginReceive/Receive 而想互不干扰,并且可以处理分包信息(而不是假设每一次 Receive 的信息都是完整的消息),并且 Send 返回数据是在消息解析中的事情(解释是在异步子线程中)而并不阻塞 BeginReceive/Receive(并不等待处理完消息Send完返回值才开始)。实际上也不轻易关闭服务。

从你的“客户端”来看,基本上你的客户端不是 web 概念。你是在 asp.net 服务器上当作客户端来看待,并不是在浏览器客户端。

通讯中要处理分包的情况,也就是接收到的信息都要放到一个 List<byte> 集合中,然后每一次 Receive 之后都要检查、解析一下这个集合的 byte[ ] ,判断是否存在一个完整的消息。例如假设你的信令规定了“第一个字节是消息长度”,那么你就从这个 byte[ ] 的第一个字节来判断一下有没有足够长度的 byes;或者比如说有的信令约定用 0d、0a
 两个字节表示消息结束。当你解析到一条完整的消息,才能进行处理。你不能在收到了不完整的 bytes 的时候就随便地执行 Encoding.XXXX.GetString(....) 这种操作。

#14


引用 10 楼 shjsmhkd 的回复:
aspx是能收的,我测试通过,就是aspx发多次时,服务器端返回多次,可aspx只接收一次,想请问有什么方法,aspx也可以接收多次??


不论是服务器端,还是客户端,接收消息都要处理分包情况,都是接收多次。不管所谓的 buffer 设置多大,不管是设置1M 还是1 byte,都需要处理分包(并不是设置越大越好,当然也不是设置为小于10k更好)。而你 Receive 一次,这显然是错误的流程。处理分包、多次 BeginReceive/Receive,解析消息,判断有没有收到一条完整的消息,只有等到收到了完整消息之后才能说处理消息并且发送返回值。

不管是短连接还是长连接 tcp 通讯,都要处理分包问题。不能忽视分包。对于你的短链接tcp 方式来说,“客户端”多次 Receive ,然后当收到了一条完整的返回消息,处理了收到的消息,就可以关闭连接了。这样服务器端也随后关闭了连接,所以服务器端并不需要关闭连接(或者其实也可以规定最长连接时间,超时则中断连接)。

#15


接收消息“是”使用 Receive,发送消息“是”使用 Send。但是许多人为什么成为标题党?为什么被不良培训者欺骗呢?就是因为把这个逻辑给理解“反了”!他以为只要是 Receive 就收到了完整消息,他把必要条件当做成充分条件,他不知道其实那些培训连入门都没有入门,因为没有告诉你程序设计方法,而只是告诉你一些简单语法而已。

我们从 tcp 角度来看看 http post 消息基本格式。在消息“头”的最后,有两个连续的 0d 0a 字节,然后是消息“体”,然后又是两个连续的 0d 0a 字节。只有当看到这样的信令格式,才开始解析这个恶 http 消息。

所以任何消息都有信令格式设计,最基本的知识要求。不是说你“随便发”、另一端“随便收”,就能学会通讯程序设计。最起码地要知道自己定义消息格式,在另一端能解析为完整的消息。

而 tcp 接收端(不管是服务器还是客户端)都是应该连续接收数据,处理分包,判断是否接收到一个完整消息。这应该记为一个常识知识。

#16


我是来看评论的,正文回复都是长篇大论啊,mark一下。

#1


随便你怎么发,一起发也行分几次发都行。对于这种自定义协议的报文,可以先收2个长度字节,然后根据得到长度再去收后续字节,有多段就以此类推

#2


 不知道你做网站为什么要这种需求。
 监听和接收都需要不停调用,要不然下次有人连你,你就连不上了。
 用多线程来搞。

如果你要区别着发,就要做个标识,要不然收到后你也没办法知道是头还是体。
一次性发也是需要做手脚来标示。

再不则我感觉最好做的就是把对像直接发过来,反正你全是字符,都是简单的类型。
直接弄成对象 序列化发过来 收到再反序列化就行了。

我是这样觉得。

#3


引用 1 楼 xdashewan 的回复:
随便你怎么发,一起发也行分几次发都行。对于这种自定义协议的报文,可以先收2个长度字节,然后根据得到长度再去收后续字节,有多段就以此类推


没太明白您说的,如果分几次发,第一次接收是长度,然后怎么接第二次后续字节呢?
请问能给个代码吗?谢了

还有就是我发了如三次,一长度,二头,三体,这三个是一个数据的总共。我再发一个数据的总共,接收时怎么判断是新的一个数据了呢??

#4


引用 3 楼 shjsmhkd 的回复:
还有就是我发了如三次,一长度,二头,三体,这三个是一个数据的总共。我再发一个数据的总共,接收时怎么判断是新的一个数据了呢??

socket这个东西不是你发几次就一定要收几次的,你可以发N次,但只要你接受的buff足够大,完全可以一行就收完,所以无需去在于收发次数。第一次收2个长度字节,然后解析得到后续还有多少数据需要接收,然后去收这点长度的数据,反复收,每收一次计算剩余长度,直到长度吻合未知。然后再接受2个长度字节,重复上述操作

#5


引用 2 楼 hiose89 的回复:
 不知道你做网站为什么要这种需求。
 监听和接收都需要不停调用,要不然下次有人连你,你就连不上了。
 用多线程来搞。

如果你要区别着发,就要做个标识,要不然收到后你也没办法知道是头还是体。
一次性发也是需要做手脚来标示。

再不则我感觉最好做的就是把对像直接发过来,反正你全是字符,都是简单的类型。
直接弄成对象 序列化发过来 收到再反序列化就行了。

我是这样觉得。


请问怎么做个标识,又怎么根据标识区分,主要是区分多段数据时,一段数据包括长度,头,体,多段时如何判断?
最好有几条代码,谢谢

#6


引用 5 楼 shjsmhkd 的回复:
Quote: 引用 2 楼 hiose89 的回复:

 不知道你做网站为什么要这种需求。
 监听和接收都需要不停调用,要不然下次有人连你,你就连不上了。
 用多线程来搞。

如果你要区别着发,就要做个标识,要不然收到后你也没办法知道是头还是体。
一次性发也是需要做手脚来标示。

再不则我感觉最好做的就是把对像直接发过来,反正你全是字符,都是简单的类型。
直接弄成对象 序列化发过来 收到再反序列化就行了。

我是这样觉得。


请问怎么做个标识,又怎么根据标识区分,主要是区分多段数据时,一段数据包括长度,头,体,多段时如何判断?
最好有几条代码,谢谢


标示这种东西任何方法都可以实现,你可以自己加一些特殊字符来区分,也有更简单来的做法。
比如JSON 就是KEY VALUES的格式。你现在的光有VALUES 所以你不知道哪一个是头哪一个是体,
当你给相应的值 加上标示键后就可以区分了啊。

接收后反序列化一下就成对象了。 

#7


还想请问大家个事,就是socket我用的是个asapx页面,不是一个应用程序

#8


还想请问大家个事,就是socket我用的是个asapx页面,不是一个应用程序,如果服务器那边是分开发的,比如发了三次,那我的一个aspx页面怎么接收三次呢,我试了下,只能接一次啊。

这个大家方便给个代码吗?谢了

#9


aspx只能发 不能收....

收的叫"服务端" 应该是一个exe 或者一个服务..而不是"网页"

#10


引用 9 楼 diaodiaop 的回复:
aspx只能发 不能收....

收的叫"服务端" 应该是一个exe 或者一个服务..而不是"网页"


aspx是能收的,我测试通过,就是aspx发多次时,服务器端返回多次,可aspx只接收一次,想请问有什么方法,aspx也可以接收多次??

#11


引用 10 楼 shjsmhkd 的回复:
aspx是能收的,我测试通过,就是aspx发多次时,服务器端返回多次,可aspx只接收一次,想请问有什么方法,aspx也可以接收多次??

web和服务器多次通信,要么轮询要么websocket

#12


哎,.

你既然都玩socket了. 你就应该知道 socket跟http(asp.net)有什么区别,

asp.net(web) 中是不能随便收发tcp/ip的...

因为他是长连接..http是短连接...这最起码的 你应该懂吧..(如果这你不懂那你没有继续看下去的必要了)

首先我们不说你具体协议如何..反正也没人看..只说流程.

你无非是想通过asp.net后台发送 socket 到"服务端(虽然我不知道你的服务端是不是也是"网页")".然后根据服务端的返回值做处理

明确的告诉你,那是不行的...

因为http在请求之后就没了...所以这个时候 你服务端可能还没有send 但是这个时候 tcpclient已经释放了 根本保持不了..

就算服务端在收到数据马上send 这个时候 也不一定能发过来..更何况这样做根本没意义..这根本就是"短链接"干的事.

长连接是无论何时的 都可以进行收发,否则他的存在也没有意义啊...更何况真正的项目中 这些东西都是异步的...

既然说到"无论何时" 那么显然 http是办不到的...

所以现在你就研究协议报文这种东西 对你来说 还是太早了..因为你连基本的"流程" 可能都不太清楚.

更何况你还让大家直接给你写出代码.....

#13


aspx 基本上是处理浏览器请求时使用,asp.net (以及 IIS)其实经常会重启你的 asp.net 应用程序的另一个进程,来解决许多问题。所以 asp.net 进程经常结束,各种内存中的状态数据经常丢失,你的程序的相关内容也会丢失。

从你的问题中的代码来看,你的“服务器端”Accept 一次,然后 Receive 一次,然后不管是不是分包的部分信息,都把这个当作完整的字符串(仅仅是字符串)执行 Console.WriteLine 输出,然后 Send 一个信息,然后就关闭服务。从这个来看,基本上是一些专门摆着让你了解一些基本语法的小例子上的代码。正常的服务流程根本不是这样的。正常的服务可以 BeginAccept/Accept 上万、几十万的请求,然后获得请求之后每一个单独的信道可以单独进行 BeginReceive/Receive 而想互不干扰,并且可以处理分包信息(而不是假设每一次 Receive 的信息都是完整的消息),并且 Send 返回数据是在消息解析中的事情(解释是在异步子线程中)而并不阻塞 BeginReceive/Receive(并不等待处理完消息Send完返回值才开始)。实际上也不轻易关闭服务。

从你的“客户端”来看,基本上你的客户端不是 web 概念。你是在 asp.net 服务器上当作客户端来看待,并不是在浏览器客户端。

通讯中要处理分包的情况,也就是接收到的信息都要放到一个 List<byte> 集合中,然后每一次 Receive 之后都要检查、解析一下这个集合的 byte[ ] ,判断是否存在一个完整的消息。例如假设你的信令规定了“第一个字节是消息长度”,那么你就从这个 byte[ ] 的第一个字节来判断一下有没有足够长度的 byes;或者比如说有的信令约定用 0d、0a
 两个字节表示消息结束。当你解析到一条完整的消息,才能进行处理。你不能在收到了不完整的 bytes 的时候就随便地执行 Encoding.XXXX.GetString(....) 这种操作。

#14


引用 10 楼 shjsmhkd 的回复:
aspx是能收的,我测试通过,就是aspx发多次时,服务器端返回多次,可aspx只接收一次,想请问有什么方法,aspx也可以接收多次??


不论是服务器端,还是客户端,接收消息都要处理分包情况,都是接收多次。不管所谓的 buffer 设置多大,不管是设置1M 还是1 byte,都需要处理分包(并不是设置越大越好,当然也不是设置为小于10k更好)。而你 Receive 一次,这显然是错误的流程。处理分包、多次 BeginReceive/Receive,解析消息,判断有没有收到一条完整的消息,只有等到收到了完整消息之后才能说处理消息并且发送返回值。

不管是短连接还是长连接 tcp 通讯,都要处理分包问题。不能忽视分包。对于你的短链接tcp 方式来说,“客户端”多次 Receive ,然后当收到了一条完整的返回消息,处理了收到的消息,就可以关闭连接了。这样服务器端也随后关闭了连接,所以服务器端并不需要关闭连接(或者其实也可以规定最长连接时间,超时则中断连接)。

#15


接收消息“是”使用 Receive,发送消息“是”使用 Send。但是许多人为什么成为标题党?为什么被不良培训者欺骗呢?就是因为把这个逻辑给理解“反了”!他以为只要是 Receive 就收到了完整消息,他把必要条件当做成充分条件,他不知道其实那些培训连入门都没有入门,因为没有告诉你程序设计方法,而只是告诉你一些简单语法而已。

我们从 tcp 角度来看看 http post 消息基本格式。在消息“头”的最后,有两个连续的 0d 0a 字节,然后是消息“体”,然后又是两个连续的 0d 0a 字节。只有当看到这样的信令格式,才开始解析这个恶 http 消息。

所以任何消息都有信令格式设计,最基本的知识要求。不是说你“随便发”、另一端“随便收”,就能学会通讯程序设计。最起码地要知道自己定义消息格式,在另一端能解析为完整的消息。

而 tcp 接收端(不管是服务器还是客户端)都是应该连续接收数据,处理分包,判断是否接收到一个完整消息。这应该记为一个常识知识。

#16


我是来看评论的,正文回复都是长篇大论啊,mark一下。