本文介绍了套接字写行为不一致?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我有一个客户端和服务器享受以下简单对话: 客户端连接 客户端发送请求 服务器发送回复 客户断开连接 这是必须的。响应必须包含在一个开始 和结束字节0x02和0x03中。 假设我有一个byte []响应: 这个失败: socket.Send(new byte [] {0x02}); // send start socket.Send(response); // send start socket.Send(new byte [] {0x03}); //发送开始 它失败了,因为客户端抛出了EOT遇到的错误 来自主机 这个工作: byte [] tmp = new byte [response.Length + 2] Array.Copy(响应0,tmp,1); tmp [0] = 0x02; tmp [tmp.Length -2] = 0x03; socket.send(tmp) 这个工作: List< ArraySegment< byte> tmp = new List< ArraySegment< byte>>(); tmp.Add(new ArraySegment< byte>(new byte [ ] {0x02})); tmp.Add(new ArraySegment< byte>(response)); tmp.Add(new ArraySegment< byte>(new byte [ ] {0x03})); socket.Send(tmp); 我启用了网络跟踪,并且在所有情况下写入的字节都是 相同,相同的数量,但日志在第一个 的情况下看起来不同(3个调用发送而不是jsut 1) 任何人都可以详细说明为什么这些工作有所不同? 解决方案 是tmp [tmp.Length -2]"一个错字?似乎应该是 " tmp [tmp.Length - 1]"相反。 您还没有发布足够的代码来明确回答。对于那个 问题,你甚至没有真正描述过这种行为吗 (究竟是什么声明抛出异常?)。 但是,因为通常你应该如何发送字节 (也就是说,它们是分组在一个数组中还是在 $ b发送一个) $ ba时间,或介于两者之间的东西),这表明 终止字节0x03是可选的,或者 响应中包含的数据。缓冲区已经包含一个终止字节。 要么解释为什么服务器可能会在 之前关闭连接,你有机会发送最后一个字节。 /> 如果那不是它,那么你应该发布一个简洁但完整的 代码样本,可以可靠地证明问题。请注意,对于网络 代码,完成代码表示连接的两端。要点 完成是的,有人可以实际运行和测试你的代码。 Pete 客户端代码是什么样的?以上应该可以工作 - 它可以结束单独的数据包发送,但是客户端应该处理它。 - Jon Skeet - < sk *** @ pobox.com> http ://www.pobox.com/~skeet 博客: http:/ /www.msmvps.com/jon.skeet 如果回复小组,请不要给我发邮件 这是一个错字,对不起 您还没有发布足够的代码来明确回答。 我断言我有。这个概念是以下方法应该等于:)发送1个字节,发送多个字节,发送1个字节 b)复制1个字节到缓冲区,复制多个字节到缓冲区,复制一个字节到 缓冲区,发送整个缓冲区 c)列出3个ArraySegment< byte> 没有例外。客户端设备是一个相对愚蠢的终端 - 准确的信用卡终端。当我以第一种方式与它进行交互时,它会丢弃连接并再次与服务器联系,每次 时间吐出一张纸说传输结束来自 主机" 后两种方式与它互动,效果很好。 就规范而言,终止0x03是强制性的。 终端和服务器之间有一个设备表格 的终端单元连接英国X25网络, 本地局域网,理论上可以自己添加这些字节,但我怀疑 这样做,因为尝试只发送消息缓冲区 而没有必需的0x02 / 0x03失败。 服务器不应该关闭连接;愚蠢的客户端得到 (一些?)无论我发送什么,转储连接和重试。我发现连接被删除了 因为我在 阻塞套接字上返回Read()并且一段时间之后它解锁了读取0字节 的确,我完全同意。这是一个很小的问题,但这可能是b $ b;如果你有一个备用信用卡终端,连接到 british X25或者可以安排这个的公司,一个ACP设备可以提供必要的X25< TCP链接然后我很乐意发送一些 工作代码。事实上,通过快速测试通常很难得到这些东西 :( 这是调试情况的难度;所有我知道 发送零碎的东西并不能正常工作,而且一次性发送确实。确实,链条的价值只会在我们的ACP之前达到它的水平。恢复 到X25。最烦人的。 I have a client and server that enjoy the following simple dialogue:Client connectsClient sends requestServer sends responseClient disconnectsThis is the way it must be. The response must be wrapped in a startand end byte 0x02 and 0x03 resepctively.suppose I have a byte[] response:THIS FAILS:socket.Send(new byte[]{ 0x02 }); //send startsocket.Send(response); //send startsocket.Send(new byte[]{ 0x03 }); //send startit fails because the client throws an error that EOT was encounteredfrom the hostTHIS WORKS:byte[] tmp = new byte[response.Length + 2]Array.Copy(response 0, tmp, 1);tmp[0] = 0x02;tmp[tmp.Length -2] = 0x03;socket.send(tmp)THIS WORKS:List<ArraySegment<byte>tmp = new List<ArraySegment<byte>>();tmp.Add(new ArraySegment<byte>(new byte[]{ 0x02 }));tmp.Add(new ArraySegment<byte>(response));tmp.Add(new ArraySegment<byte>(new byte[]{ 0x03 }));socket.Send(tmp);I enabled network tracing and in all cases the bytes written are thesame, same number of them, but the logs do look different in the firstcase (3 calls to Send instead of jsut 1)Can anyone shed any light on why these work any differently? 解决方案Is "tmp[tmp.Length -2]" a typo? Seems like that should be"tmp[tmp.Length - 1]" instead.You haven''t posted enough code to answer definitively. For thatmatter, you haven''t really even described the behavior precisely enough(on what statement exactly is the exception thrown?).However, since normally it should not matter how you send the bytes(that is, whether they are grouped in a single array or are sent one ata time, or something in between), that suggests that either thetermination byte 0x03 is optional, or the data contained in the"response" buffer already includes a termination byte.Either would explain why the server might close the connection beforeyou get a chance to send that last byte.If that''s not it, then you should post a concise-but-complete sample ofcode that reliably demonstrates the problem. Note that for networkingcode, "complete" means both ends of the connection. The point of"complete" is so that someone can actually run and test your code.PeteWhat does the client code look like? The above should work - it may endup getting sent on separate packets, but the client should handle that.--Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeetIf replying to the group, please do not mail me tooIt is a typo, sorryYou haven''t posted enough code to answer definitively.I''d assert I have. The concept is that the following approaches oughtto be equivalent:a) Send 1 byte, Send many bytes, Send 1 byteb) copy 1 byte to buffer, copy many bytes to buffer, copy one byte tobuffer, send entire bufferc) make a list of 3 ArraySegment<byte>There is no exception. The client device is a relatively dumb terminal- a credit card terminal to be precise. When I interact with it in thefirst way, it drops the conenction and contacts the server again, eachtime spitting out a piece of paper saying "End of Transmission fromhost"Interact with it in the latter two ways and it works perfectly.The terminating 0x03 is mandatory, as far as the spec is concerned.There is a device in between the terminal and the server in the formof a terminating unit that connects the british X25 network, with thelocal LAN, which could in theory add these bytes itself, but I doubtthat it does this, because attempting to send just the message bufferwithout the requisite 0x02 / 0x03 fails.The server isnt supposed to close the connection; the dumb client gets(some of?) whatever I send, dumps the connection and retries. I findout the connection was dropped because I return to Read() on ablocking socket and some time later it unblocks having read 0 bytesIndeed, and I totally agree. THere is a small problem with thisthough; If you have a spare credit card terminal, a connection to thebritish X25 or a company that can arrange this, an ACP device toprovide the necessary X25 <TCP link then I''ll gladly send someworking code. As it is, those things are usually pretty hard to comeby to run a quick test :(Such is the difficulty of debugging the situation; all i know is thatsending piecemeal doesnt work, and sending in one go does. Indeed theTCP-ness of the chain will only go as far as our ACP before it revertsto X25. Most irritating. 这篇关于套接字写行为不一致?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-05 13:48