- 浏览: 235080 次
- 性别:
- 来自: 上海
最新评论
-
iwindyforest:
pinocchio2mx 写道iwindyforest 写道H ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
nng119:
找不到设备的安装信息 这个问题怎么解决的?
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
pinocchio2mx:
iwindyforest 写道Hi pinocchio2mx ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
iwindyforest:
Hi pinocchio2mx 兄弟, 这个镜像是好的, 我安 ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
pinocchio2mx:
蛋疼啊,折腾一晚上还没搞定!网上的教程没一篇靠谱的,摸摸索索到 ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite
我在一个项目中碰到了一个TcpSocket的应用。在java程序中使用TcpSocket同本机的一个服务进行进程间的通信。
由于通信路径只是单机并没有经过网络,因此两个进程之间的互通相对与网络传输是比较快速的。因此,进程间的交互使用了如下方式:
(见上传图片)
让我们看一下代码实现:
我们通过调用sendAndReceiveOnce()来接收并返回数据。
这样实现会导致什么问题呢?
1. 最明显的就是发送数据,和接收数据在同一个线程里边,如果运行在主线程,那么主线程将会在执行receiveOnce()的时候停滞,除非接收到数据或者触发超时异常。但之前已经说明了,应用本函数的环境是单机的进程间的通信,因此接收到数据的时间实际上就取决于Server处理并给予响应时间的长短,不存在网络传输的滞留时间。所以,如果在Server响应快速的情况下,客户端Socket几乎感觉不到延迟太多。
2. 再一个明显问题就是,receiveOnce()根据其函数名称就可以得知,它只能读取一次,如果返回信息的长度,大于其缓冲区的长度,那它只能得到部分数据了。
综合分析以上两种情况,我们先解决问题2吧,看看如何读取完整的响应信息?
下面是我的实现方法:
这个方法就如同它的注释所说的那样,它总是尝试去仅可能多的读取信息,但是在触发了一次超时之后将会返回读取到的字节。
有人提问:那判断流是否已经读完不是看读到最后会返回-1么?
我的回答是:返回-1取决于处理的流的源头是什么,如果是文件流,这种想法或许是对的,因为文件流的大小是固定的,持续的读,总会读到文件的末尾(EOF),它总会返回-1的。
就像下面的文件流在读取文件的实现一样,我们这样读取文件流:
但是,如果是网络流,例如TcpSocket,这样的流是没有末尾(EOF)的,如果你想读到-1,或许在远端被关闭了,而你还在读取,还是有可能读到-1的。实际情况是:网络连接状况很复杂,很有可能远端没有正常关闭而是进程死掉了,而是连接的线路断掉了,或者任何一个原因导致连接的通路无法正常传输数据。由于在这种情况下,java中BufferedInputStream的read(byte[] b, int off, int len)函数(其它流对象也一样)总是尝试读取更多的数据,如果没有设置超时,就会一直堵塞在那里,像死掉了一样。而不是像你所期待的那样,返回-1。因此,我们才才用让它最少经过一次超时,来尝试读取更多的数据。当然,这也是仅仅在网络状况足够好的情况下,或者超时对于响应结果不会影响太多的情况下的解决方法。
(加一个小插曲:前段时间本人曾经在电话里面被一个面试我的作开发的兄弟考到“怎么获取tcpScoket远端关闭”,我就是阐述了因为以上观点“检测远端是否关闭的最好方法就是向远端发送数据,看是否发生IO异常”,而那位仁兄一直坚持远端关闭得到-1是对的,我说不对就反问:如果不是关闭,而是把网线切断或者网络不通也能得到-1么?仁兄语塞,面试后来以尴尬结束。后来反思自己当时实在太轻狂了,没给仁兄面子。去不去应聘倒无所谓,但是态度还是不是面试时应该有的态度啊。现在想向那位仁兄道歉,也没机会了)
那现在又有一个问题了,虽然与远端的交互出现无法读取到数据的时候不会一直堵塞在那里,像死掉了一样。但是我在使用blockReceive()的时候总是需要等一个超时的时间才能返回!
那我如果设超时为5秒,操作完了之后,也至少等到5秒才能达到消息的反馈。哦,天哪,慢到要死了!!!!
这个问题必须解决,那么:
让我们用更聪明的实现方法吧,我们不要阻塞了!!!
我们发现:这个方法真是不错!我们每次在读取数据之前,总是先用available()方法获取流中当前的最大可读字节数,然后再读。否则,我直接返回。但是为了以防我在读取数据的时候也出现超时问题导致堵塞,我还是小心的加入了超时的处理,虽然它在绝大部分情况下并不会发生。
好了!现在我们满怀希望的来调用所谓的“完美”解决方案:
然后,测试,却发现了一个奇怪的现象:
我们在程序里面连续调用了两次sendAndUnblockReceive(),并期待每次发送都会迅速并完整准确的接收它们每次的响应。但是,没有效果。事实是:我第一次发送的请求,并没有接收到它需要的正确响应。而我们第二次发送的请求,却接收到了第一次的响应,还要第二次的响应,这样两条数据!!!
这是为什么呢?因为:
我们第一次在发送完数据之后,马上就调用了unblocReceive()。但是由于这次我们调用的实在太快了,Server那一端没来的及处理,甚至没来的及接收,更不用说响应了。因此unblocReceive()里面我们用available()方法获取流中当前的最大可读字节数为0!!!因此,当然就不会读取了!!!而第二次再发送时,第一次的响应刚刚到达,因此,unblocReceive()再被第二次调用的时候“尽最大可能”的读取到了这两次的响应信息。
唉,看来就没有更好的方法了么?或许,还是有的吧!!!
我们先这样改一下:
强制的让线程在发送完后sleep一端时间,半秒钟,给Server足够的响应时间,然后再去读取,或许,这样比那个blockReceive()的实现要好一点吧。
最后来一下总结:
我们在这个TcpScoket中,在发送和读取使用同一线程的情况下,使用了三种读取方式:
一次读取,阻塞式完整读取,非阻塞式完整读取。
这三种读取方式的优缺点分析如下:
一次读取receiveOnce(): 是最快速,并且在缓冲区足够大的情况下能够完整读取的方法,当然如果没有设置超时,它仍然用可能存在阻塞。
阻塞式完整读取blockReceive():在返回数据之前总是至少经过一次超时以读取更多数据,因此在网络状况足够好的情况下,速度仍然比较慢。
非阻塞式完整读取unblocReceive(): 在尝试读取数据之前,首先判断可以读取的最大字节数,如果有数据则尝试去读,否则直接返回。所有是这一种不用考虑缓冲区大小,还能兼顾速度的方法。但是如果远端响应慢的情况下,依然会错过读取数据。
综合上述三中读取方式:我们可以在确定返回数据量较少,而又要求速度快而准确的情况下,使用receiveOnce()。在返回数据量较多,而又要求速度快而准确的情况下,使用unblocReceive(),不过需要留给远端足够的响应时间。在不需要响应速度很快,而需要返回大量数据,而且准确的情况下使用blockReceive()。
现在我们抛开这些,想一想:
我们真的需要这样三种读取方式吗?需要吗?
我们为什么这么罗里罗嗦使用这三种方式?
因为,我们把发送数据,和接收数据这两个功能放在一个线程里执行了!!!
这才是最主要的问题!
因此,:
尽量不要在使用Socket的流的时候,把发送数据和接收数据的调用放在一个线程里。
因为,网络上的流是不稳定的,因此java在设计流的时候也是尽量去读取尽可能多的数据,很可能发生堵塞。如果放在一个线程里面,试图我发送了就会想当然的又快又准确的接收到,就会像上面的解决方案一样,用尽招数,仍然束手无策。
由于通信路径只是单机并没有经过网络,因此两个进程之间的互通相对与网络传输是比较快速的。因此,进程间的交互使用了如下方式:
(见上传图片)
让我们看一下代码实现:
public synchronized void send(byte[] bytes) throws IOException { if (bytes != null && bytes.length > 0) { this.bos.write(bytes); this.bos.flush(); } } /** * 尝试读取一次,速度最快,但返回的信息可能不全 */ public synchronized byte[] receiveOnce() throws IOException { byte[] reciveBytes = new byte[0]; int len = this.bis.read(this.b_buf, 0, this.bufferSize); return ArrayUtils.addAll(reciveBytes, ArrayUtils.subarray(this.b_buf, 0, len)); } /** * 用于发送并接收数据,在返回数据比较少的情况下使用 */ public byte[] sendAndReceiveOnce(byte[] bytes) throws IOException { this.send(bytes); return this.receiveOnce(); }
我们通过调用sendAndReceiveOnce()来接收并返回数据。
这样实现会导致什么问题呢?
1. 最明显的就是发送数据,和接收数据在同一个线程里边,如果运行在主线程,那么主线程将会在执行receiveOnce()的时候停滞,除非接收到数据或者触发超时异常。但之前已经说明了,应用本函数的环境是单机的进程间的通信,因此接收到数据的时间实际上就取决于Server处理并给予响应时间的长短,不存在网络传输的滞留时间。所以,如果在Server响应快速的情况下,客户端Socket几乎感觉不到延迟太多。
2. 再一个明显问题就是,receiveOnce()根据其函数名称就可以得知,它只能读取一次,如果返回信息的长度,大于其缓冲区的长度,那它只能得到部分数据了。
综合分析以上两种情况,我们先解决问题2吧,看看如何读取完整的响应信息?
下面是我的实现方法:
/** * 从流的开头开始读取,读取全部的输入数据并返回 如果执行read的时候流中没有数据则阻塞读取直到超时 * 最少经过一次超时,因此速度比较慢,但读的时候流中没有数据可以等到超时 ,因此获取数据比较准确 * * @return * @throws 除了SocketTimeoutException的一切IOException */ public synchronized byte[] blockReceive() throws IOException { byte[] reciveBytes = new byte[0]; // 偏移量 int offset = 0; // 每次读取的字节数 int len = 0; while(len != -1) { try { len = this.in.read(this.buffer, 0, this.bufferSize); } catch(SocketTimeoutException e) { break; } if(len != -1) { reciveBytes = ArrayUtils.addAll(reciveBytes, ArrayUtils .subarray(this.buffer, 0, len)); offset = offset + len; } } return reciveBytes; }
这个方法就如同它的注释所说的那样,它总是尝试去仅可能多的读取信息,但是在触发了一次超时之后将会返回读取到的字节。
有人提问:那判断流是否已经读完不是看读到最后会返回-1么?
我的回答是:返回-1取决于处理的流的源头是什么,如果是文件流,这种想法或许是对的,因为文件流的大小是固定的,持续的读,总会读到文件的末尾(EOF),它总会返回-1的。
就像下面的文件流在读取文件的实现一样,我们这样读取文件流:
protected byte[] receiveBytes() throws IOException { byte[] reciveBytes = new byte[0]; // 偏移量 int offset = 0; // 每次读取的字节数 int len = 0; while(len != -1) { this.buffer = new byte[bufferSize]; len = this.in.read(this.buffer, 0, this.bufferSize); if(len != -1) { reciveBytes = ArrayUtils.addAll(reciveBytes, this.buffer); offset = offset + len; } } return ArrayUtils.subarray(reciveBytes, 0, offset); }
但是,如果是网络流,例如TcpSocket,这样的流是没有末尾(EOF)的,如果你想读到-1,或许在远端被关闭了,而你还在读取,还是有可能读到-1的。实际情况是:网络连接状况很复杂,很有可能远端没有正常关闭而是进程死掉了,而是连接的线路断掉了,或者任何一个原因导致连接的通路无法正常传输数据。由于在这种情况下,java中BufferedInputStream的read(byte[] b, int off, int len)函数(其它流对象也一样)总是尝试读取更多的数据,如果没有设置超时,就会一直堵塞在那里,像死掉了一样。而不是像你所期待的那样,返回-1。因此,我们才才用让它最少经过一次超时,来尝试读取更多的数据。当然,这也是仅仅在网络状况足够好的情况下,或者超时对于响应结果不会影响太多的情况下的解决方法。
(加一个小插曲:前段时间本人曾经在电话里面被一个面试我的作开发的兄弟考到“怎么获取tcpScoket远端关闭”,我就是阐述了因为以上观点“检测远端是否关闭的最好方法就是向远端发送数据,看是否发生IO异常”,而那位仁兄一直坚持远端关闭得到-1是对的,我说不对就反问:如果不是关闭,而是把网线切断或者网络不通也能得到-1么?仁兄语塞,面试后来以尴尬结束。后来反思自己当时实在太轻狂了,没给仁兄面子。去不去应聘倒无所谓,但是态度还是不是面试时应该有的态度啊。现在想向那位仁兄道歉,也没机会了)
那现在又有一个问题了,虽然与远端的交互出现无法读取到数据的时候不会一直堵塞在那里,像死掉了一样。但是我在使用blockReceive()的时候总是需要等一个超时的时间才能返回!
那我如果设超时为5秒,操作完了之后,也至少等到5秒才能达到消息的反馈。哦,天哪,慢到要死了!!!!
这个问题必须解决,那么:
让我们用更聪明的实现方法吧,我们不要阻塞了!!!
/** * 如果流中有数据,则从流的开头开始读取,读取全部的输入数据并返回,否则马上返回空 尝试获取当前流中的最大数据量, * 由于使用了非阻塞接收,需要保证在执行本函数的时候流中恰好有数据, 在执行此函数之前必须给后台足够的响应时间 * * @return * @throws 除了SocketTimeoutException的一切IOException */ public synchronized byte[] unblocReceive() throws IOException { byte[] reciveBytes = new byte[0]; // 当前流中的最大可读数 int contentLength = this.in.available(); // 偏移量 int offset = 0; // 每次读取的字节数 int len = 0; while(contentLength > 0 && offset < contentLength && len != -1) { try { len = this.in.read(this.buffer, 0, this.bufferSize); } catch(SocketTimeoutException e) { break; } if(len != -1) { reciveBytes = ArrayUtils.addAll(reciveBytes, ArrayUtils .subarray(this.buffer, 0, len)); offset = offset + len; } } return reciveBytes; }
我们发现:这个方法真是不错!我们每次在读取数据之前,总是先用available()方法获取流中当前的最大可读字节数,然后再读。否则,我直接返回。但是为了以防我在读取数据的时候也出现超时问题导致堵塞,我还是小心的加入了超时的处理,虽然它在绝大部分情况下并不会发生。
好了!现在我们满怀希望的来调用所谓的“完美”解决方案:
public byte[] sendAndUnblockReceive(byte[] bytes) throws IOException { this.send(bytes); return this.unblocReceive(); }
然后,测试,却发现了一个奇怪的现象:
我们在程序里面连续调用了两次sendAndUnblockReceive(),并期待每次发送都会迅速并完整准确的接收它们每次的响应。但是,没有效果。事实是:我第一次发送的请求,并没有接收到它需要的正确响应。而我们第二次发送的请求,却接收到了第一次的响应,还要第二次的响应,这样两条数据!!!
这是为什么呢?因为:
我们第一次在发送完数据之后,马上就调用了unblocReceive()。但是由于这次我们调用的实在太快了,Server那一端没来的及处理,甚至没来的及接收,更不用说响应了。因此unblocReceive()里面我们用available()方法获取流中当前的最大可读字节数为0!!!因此,当然就不会读取了!!!而第二次再发送时,第一次的响应刚刚到达,因此,unblocReceive()再被第二次调用的时候“尽最大可能”的读取到了这两次的响应信息。
唉,看来就没有更好的方法了么?或许,还是有的吧!!!
我们先这样改一下:
public byte[] sendAndUnblockReceive(byte[] bytes) throws IOException { this.send(bytes); // 由于使用了非阻塞接收,为保证在执行read的时候流中恰好有数据, // 必须给后台足够的响应时间 try { Thread.sleep(500); } catch (InterruptedException e) { logger.error("InterruptedException error.", e); } return this.unblocReceive(); }
强制的让线程在发送完后sleep一端时间,半秒钟,给Server足够的响应时间,然后再去读取,或许,这样比那个blockReceive()的实现要好一点吧。
最后来一下总结:
我们在这个TcpScoket中,在发送和读取使用同一线程的情况下,使用了三种读取方式:
一次读取,阻塞式完整读取,非阻塞式完整读取。
这三种读取方式的优缺点分析如下:
一次读取receiveOnce(): 是最快速,并且在缓冲区足够大的情况下能够完整读取的方法,当然如果没有设置超时,它仍然用可能存在阻塞。
阻塞式完整读取blockReceive():在返回数据之前总是至少经过一次超时以读取更多数据,因此在网络状况足够好的情况下,速度仍然比较慢。
非阻塞式完整读取unblocReceive(): 在尝试读取数据之前,首先判断可以读取的最大字节数,如果有数据则尝试去读,否则直接返回。所有是这一种不用考虑缓冲区大小,还能兼顾速度的方法。但是如果远端响应慢的情况下,依然会错过读取数据。
综合上述三中读取方式:我们可以在确定返回数据量较少,而又要求速度快而准确的情况下,使用receiveOnce()。在返回数据量较多,而又要求速度快而准确的情况下,使用unblocReceive(),不过需要留给远端足够的响应时间。在不需要响应速度很快,而需要返回大量数据,而且准确的情况下使用blockReceive()。
现在我们抛开这些,想一想:
我们真的需要这样三种读取方式吗?需要吗?
我们为什么这么罗里罗嗦使用这三种方式?
因为,我们把发送数据,和接收数据这两个功能放在一个线程里执行了!!!
这才是最主要的问题!
因此,:
尽量不要在使用Socket的流的时候,把发送数据和接收数据的调用放在一个线程里。
因为,网络上的流是不稳定的,因此java在设计流的时候也是尽量去读取尽可能多的数据,很可能发生堵塞。如果放在一个线程里面,试图我发送了就会想当然的又快又准确的接收到,就会像上面的解决方案一样,用尽招数,仍然束手无策。
评论
1 楼
presses
2008-07-08
一、TCP层很多都实现了保活定时器,当客户端socket断开时,服务端对应的socket会自动抛出异常。
所以不需要靠读到"-1"来判断socket的关闭。
二、如果客户端和服务端用Socket传输信息,最好有自已的协议,例如用一串特殊字符(magic number)时来分割数据,当 一端读到magic number时,就把数据返回给业务层处理。
三、对这类Socket应用,最好还是多线程吧。用多线程的原因并不仅仅是处理网络延时。处理并发等,也是原因。
所以不需要靠读到"-1"来判断socket的关闭。
二、如果客户端和服务端用Socket传输信息,最好有自已的协议,例如用一串特殊字符(magic number)时来分割数据,当 一端读到magic number时,就把数据返回给业务层处理。
三、对这类Socket应用,最好还是多线程吧。用多线程的原因并不仅仅是处理网络延时。处理并发等,也是原因。
发表评论
-
利用归并排序算法对大文件进行排序
2015-01-25 20:59 5627归并排序算法介绍,请参照Wikipeida zh. ... -
try-catch影响性能吗?
2014-07-09 17:06 1682try-catch会影响性能吗? try-catch放在循 ... -
Java Concurrency In Practice Learning Note
2014-06-17 11:13 0Frameworks introduce concurre ... -
Java collections overview
2014-03-21 10:37 868Fromp: http://java-performance ... -
JVM Learning Note 4 -- HotSpot JVM Options List
2014-02-26 11:08 1032From: http://www.oracle.c ... -
Eclispe 性能优化
2014-02-25 15:07 939我目前Eclipse所在的机器环境是windows x32 ... -
JVM Learning Note 3 -- JVM Performance Monitor Tools
2014-02-25 12:25 1173JDK Provided Tools Comman ... -
JVM Performance Monitor Tools
2014-02-25 11:12 5JDK Provide Tools Command Li ... -
JVM Learning Note 2 -- Garbage Collection and Memory Allocation Strategy
2014-02-18 14:57 1762Method to check if an object ... -
JVM Learning Note 1 -- Run-Time Data Areas and Object Representation
2014-02-11 00:44 876Run-Time Data Areas Clas ... -
String.intern()方法
2014-02-10 16:22 786intern public String intern() ... -
GlobalKnowledge: 2013 IT 技能薪水报告
2014-01-09 18:24 1875from: GlobalKnowledge http:/ ... -
OLTP Vs OLAP
2014-01-02 13:42 839OLTP vs. OLAP We can divide ... -
java的字符串拼接
2013-12-31 16:43 815每当我用+运算符拼接字符串时, 总有人跟我提出你应该 ... -
45 Useful JavaScript Tips, Tricks and Best Practices
2013-12-31 11:08 10222By Saad Mousliki ... -
面试10大算法汇总+常见题目解答
2013-12-16 18:03 1999面试10大算法汇总+常见题目解答 最近更新 ... -
面试关于HashMap的工作原理
2013-12-16 17:58 1979先来些简单的问题 “你用过HashMap吗?” ... -
处理 InterruptedException
2013-11-01 16:28 745这样的情景您也许并不陌生:您在编写一个测试程序,程序需要暂 ... -
Java正确处理InterruptedException的方法
2013-11-01 16:24 802要想讨论正确处理Interr ... -
Overview To CMMI v1.3
2013-07-05 18:15 912What is CMMI? CMMI® (Capa ...
相关推荐
TCP套接字(TCP Socket)是网络编程中的一个重要概念,它是基于传输控制协议TCP的应用程序接口,用于在互联网上实现两台计算机之间的可靠通信。TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,而套接字...
最近有个项目模块需要用到TCP Socket通讯,遇到了一个大坑,所以做了这个Demo。 本Demo主要实现了安卓(Android)TCP 客户端(Client)和服务器(Server)Demo的Socket通讯。以及对接硬件的项目数据在十六进制&&byte&&int...
首先,TCP是一种面向连接的、可靠的传输协议,它确保了数据的顺序传输和无丢失特性,非常适合于需要高稳定性的应用,如文件传输、远程登录等。GPRS是2G移动通信系统的一种增强型数据服务,允许移动设备通过蜂窝网络...
总结起来,"TCPSOCKET线程池通信客户端+服务器端示例代码"是.NET开发者学习如何利用TCP SOCKET进行高效、多线程通信的宝贵资源。通过理解和实践这个示例,开发者可以更好地掌握网络编程技术,为开发高性能的网络应用...
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在C#中,我们可以使用System.Net.Sockets命名空间下的TcpListener和TcpClient类来实现TCP Socket编程。下面将详细介绍...
首先,我们要理解TCP是一种面向连接的、可靠的传输协议,它通过三次握手建立连接,保证数据的有序性和无损性。Socket则是应用层与TCP/IP协议族通信的抽象表示,它为程序员提供了一种标准的接口,以便进行网络通信。 ...
4. 通过`Socket`对象的`getInputStream()`和`getOutputStream()`方法获取输入流和输出流,用于读取客户端的数据和向客户端发送数据。 5. 处理客户端的数据,例如,根据接收到的字符进行某种操作,然后将结果通过输出...
首先,TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它通过三次握手建立连接,并在数据传输过程中进行错误检测和纠正,确保数据的完整性和顺序性。在Qt5中,QTcpSocket类为开发者提供了...
在QT中,TCP Socket通信是网络编程的重要部分,允许程序间通过Internet进行数据传输。本示例将深入讲解如何在QT中实现TCP Socket通信。 首先,TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于...
标题"C# TCPSocket"指的是使用C#编程语言实现的TCP Socket通信库。TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,广泛用于互联网上的应用程序,如服务器和客户端之间...
首先,TCP是一种面向连接的、可靠的传输协议,它确保数据的顺序传输和无丢失性,非常适合于物联网(IoT)等场景,需要稳定的数据交互。C#中的System.Net.Sockets命名空间提供了对TCP套接字的支持,允许开发者创建...
本主题将深入讲解如何利用TCP Socket编程实现自定义数据帧进行长数据传输,特别是图片的发送与接收。 TCP协议保证了数据的顺序和可靠性,通过三次握手建立连接,并使用滑动窗口机制来控制流量和确认数据包的接收。...
`TcpSocket`和`Socket`是.NET框架中用于TCP(传输控制协议)通信的关键类,它们为开发者提供了在网络层面上建立和管理连接的能力。本文将深入探讨这两个概念以及异步编程在以太网通讯中的应用。 首先,让我们理解...
在Android开发中,TCP Socket通信是移动应用与服务器进行数据交互的一种常见方式。TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,确保了数据的顺序传输和数据完整性...
TcpClient是更高层次的抽象,它提供了一种更加方便的方式来创建和管理TCP连接,而TcpSocket则更接近底层,提供了更多的自定义选项,但同时也需要开发者处理更多的细节。 TcpClient类通常用于客户端,它的主要功能是...
总之,TCP Socket编程是C#开发网络应用的基础,通过理解并掌握其原理和实现方式,开发者能够构建稳定、可靠的网络通信系统。在实践中,结合具体的业务需求,对TCP Socket进行封装和优化,可以创建出高效、易用的网络...
通过以上讲解,我们可以了解到C#中TCP Socket通信的基本原理和实现方式,无论是服务器端还是客户端,都涉及到了Socket类的创建、连接、数据交换等关键步骤。掌握这些知识点对于进行网络编程是非常重要的。
"socket获取2D激光雷达tcp数据"这个主题聚焦于如何利用C#编程语言通过Socket接口与2D激光雷达进行通信,接收并处理来自兴颂LE系列激光雷达的数据。下面将详细介绍这个过程涉及的关键知识点。 首先,2D激光雷达是一...
在Java、C++、Python等编程语言中,程序员可以创建和操作TcpSocket对象来实现网络数据交换。 描述中提到的“这是在学习过程中写的一个socket程序”,暗示我们将讨论的是一个基础的TCP客户端和服务器端的实现。通常...