TCP怎么实现即时通信

时间:2021-02-11 13:25:08
利用TCP,建立连接后,一方发送信息,另一方能不能立刻接收到这个信息并做出响应?还是只能是定时从Reader中判断是否有信息?

10 个解决方案

#1


晕。竟然从这个角度提出问题。

windows 下的 tcp 通讯双向、异步、基于IOCP。消息从一端到达另一端,触发中断事件,引起你的应用程序的“委托方法”在子线程中的异步回调。也就是说,一旦收到消息,立刻执行。不需要轮询和阻塞 Read。

轮询和阻塞的设计方式,是30年前的 unix 系列的最原始的低级的操作系统处理代码,出现在几十年前的教科书中。那么 .net 中自然也实现了最原始的教科书上的低级功能。而一些 java 书籍比较垃圾,只会照抄最原始的编程方式。

实际上这种低级功能应该禁用。应该使用异步并发的 BeginRead、BeginWrite 方式,并且保证使用windows的 IOCP 能力。

#2


简单点回答:

不是“能不能”,而是必须立刻接收到消息。那些不能立刻接收消息的轮询写法、阻塞写法,就好像有的人用 vb.net V14.0 偏要它能编译 vb4.0 的代码一样,是古老的做法。

#3


C#的socket可以基于事件编程,收到信息立即响应

#4


引用 1楼以专业开发人员为伍 的回复:
晕。竟然从这个角度提出问题。

windows 下的 tcp 通讯双向、异步、基于IOCP。消息从一端到达另一端,触发中断事件,引起你的应用程序的“委托方法”在子线程中的异步回调。也就是说,一旦收到消息,立刻执行。不需要轮询和阻塞 Read。

轮询和阻塞的设计方式,是30年前的 unix 系列的最原始的低级的操作系统处理代码,出现在几十年前的教科书中。那么 .net 中自然也实现了最原始的教科书上的低级功能。而一些 java 书籍比较垃圾,只会照抄最原始的编程方式。

实际上这种低级功能应该禁用。应该使用异步并发的 BeginRead、BeginWrite 方式,并且保证使用windows的 IOCP 能力。
谢谢指导,收益颇多。
仍有问题,为何我在tcpclient里找不到有任何事件,看楼下的兄台说,只有socket才能进行基于事件的编程吗?但我记得tcpclient是对socket的封装?
望指导。

#5


楼上不是说了使用委托异步回调吗?
public System.IAsyncResult BeginConnect(System.Net.IPAddress address, int port, System.AsyncCallback requestCallback, object state)
    System.Net.Sockets.TcpClient 的成员

#6


引用 4 楼 weixin_35777521 的回复:
Quote: 引用 1楼以专业开发人员为伍 的回复:
晕。竟然从这个角度提出问题。

windows 下的 tcp 通讯双向、异步、基于IOCP。消息从一端到达另一端,触发中断事件,引起你的应用程序的“委托方法”在子线程中的异步回调。也就是说,一旦收到消息,立刻执行。不需要轮询和阻塞 Read。

轮询和阻塞的设计方式,是30年前的 unix 系列的最原始的低级的操作系统处理代码,出现在几十年前的教科书中。那么 .net 中自然也实现了最原始的教科书上的低级功能。而一些 java 书籍比较垃圾,只会照抄最原始的编程方式。

实际上这种低级功能应该禁用。应该使用异步并发的 BeginRead、BeginWrite 方式,并且保证使用windows的 IOCP 能力。
谢谢指导,收益颇多。
仍有问题,为何我在tcpclient里找不到有任何事件,看楼下的兄台说,只有socket才能进行基于事件的编程吗?但我记得tcpclient是对socket的封装?
望指导。



TcpClinet 也好, Socket 也好,只是提供一个缓存给你。至于怎么读,同步读写,还是异步读写都要程序员自己实现。

详细可看 MSDN:
tcpclient: https://msdn.microsoft.com/zh-cn/library/system.net.sockets.tcpclient(VS.80).aspx
socket: https://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket(v=vs.110).aspx

附,如果你对网络不是很熟悉,还是用 tcpclient 吧,简单些。。

#7


tcplistener/tcpclient 不是基于事件而设计,它输出 NetworkStream,而这个 Stream 可以使用 BeginRead、BeginWrite 来异步操作(异步回调)。

虽然 tcpclient/tcplistener 内部可以返回 socket 对象,但是它重构了底层代码,它直接支持 IOCP。而Socket 类并不自动支持 IOCP,是与 linux 系列兼容的设计。

所以你应该尽量使用 TcpListener/Tcpclient 类以及 NetworkStream,尽量不要使用 Socket 类。

#8


所谓“对socket的封装”这是一个模糊的说法。接口上的封装,往往是底层有重写。

有些人脑子里的“封装”就是旧瓶装新酒式的概念,他不理解软件上的封装的含义是重写底层。放到他那里就把封装说成了高级的东西是简单拼凑低级东西了。

有没有一种高级的东西是简单拼凑低级的东西?有很多。

但是 TcpListener/TcpClient 不是这类“封装”概念,其底层与 Socket 的底层有很大的不同。

#9


引用 8 楼 sp1234 的回复:
所谓“对socket的封装”这是一个模糊的说法。接口上的封装,往往是底层有重写。

有些人脑子里的“封装”就是旧瓶装新酒式的概念,他不理解软件上的封装的含义是重写底层。放到他那里就把封装说成了高级的东西是简单拼凑低级东西了。

有没有一种高级的东西是简单拼凑低级的东西?有很多。

但是 TcpListener/TcpClient 不是这类“封装”概念,其底层与 Socket 的底层有很大的不同。


为什么封装是重写底层呢,能稍微展开解释下吗?

#10


引用 9 楼 Seilboy 的回复:
Quote: 引用 8 楼 sp1234 的回复:

所谓“对socket的封装”这是一个模糊的说法。接口上的封装,往往是底层有重写。

有些人脑子里的“封装”就是旧瓶装新酒式的概念,他不理解软件上的封装的含义是重写底层。放到他那里就把封装说成了高级的东西是简单拼凑低级东西了。

有没有一种高级的东西是简单拼凑低级的东西?有很多。

但是 TcpListener/TcpClient 不是这类“封装”概念,其底层与 Socket 的底层有很大的不同。


为什么封装是重写底层呢,能稍微展开解释下吗?



不要想太多, TcpClient 就是调用 Socket 的。
无论是看直接源代码还是运行时代码跟踪,结果都一样。。

#1


晕。竟然从这个角度提出问题。

windows 下的 tcp 通讯双向、异步、基于IOCP。消息从一端到达另一端,触发中断事件,引起你的应用程序的“委托方法”在子线程中的异步回调。也就是说,一旦收到消息,立刻执行。不需要轮询和阻塞 Read。

轮询和阻塞的设计方式,是30年前的 unix 系列的最原始的低级的操作系统处理代码,出现在几十年前的教科书中。那么 .net 中自然也实现了最原始的教科书上的低级功能。而一些 java 书籍比较垃圾,只会照抄最原始的编程方式。

实际上这种低级功能应该禁用。应该使用异步并发的 BeginRead、BeginWrite 方式,并且保证使用windows的 IOCP 能力。

#2


简单点回答:

不是“能不能”,而是必须立刻接收到消息。那些不能立刻接收消息的轮询写法、阻塞写法,就好像有的人用 vb.net V14.0 偏要它能编译 vb4.0 的代码一样,是古老的做法。

#3


C#的socket可以基于事件编程,收到信息立即响应

#4


引用 1楼以专业开发人员为伍 的回复:
晕。竟然从这个角度提出问题。

windows 下的 tcp 通讯双向、异步、基于IOCP。消息从一端到达另一端,触发中断事件,引起你的应用程序的“委托方法”在子线程中的异步回调。也就是说,一旦收到消息,立刻执行。不需要轮询和阻塞 Read。

轮询和阻塞的设计方式,是30年前的 unix 系列的最原始的低级的操作系统处理代码,出现在几十年前的教科书中。那么 .net 中自然也实现了最原始的教科书上的低级功能。而一些 java 书籍比较垃圾,只会照抄最原始的编程方式。

实际上这种低级功能应该禁用。应该使用异步并发的 BeginRead、BeginWrite 方式,并且保证使用windows的 IOCP 能力。
谢谢指导,收益颇多。
仍有问题,为何我在tcpclient里找不到有任何事件,看楼下的兄台说,只有socket才能进行基于事件的编程吗?但我记得tcpclient是对socket的封装?
望指导。

#5


楼上不是说了使用委托异步回调吗?
public System.IAsyncResult BeginConnect(System.Net.IPAddress address, int port, System.AsyncCallback requestCallback, object state)
    System.Net.Sockets.TcpClient 的成员

#6


引用 4 楼 weixin_35777521 的回复:
Quote: 引用 1楼以专业开发人员为伍 的回复:
晕。竟然从这个角度提出问题。

windows 下的 tcp 通讯双向、异步、基于IOCP。消息从一端到达另一端,触发中断事件,引起你的应用程序的“委托方法”在子线程中的异步回调。也就是说,一旦收到消息,立刻执行。不需要轮询和阻塞 Read。

轮询和阻塞的设计方式,是30年前的 unix 系列的最原始的低级的操作系统处理代码,出现在几十年前的教科书中。那么 .net 中自然也实现了最原始的教科书上的低级功能。而一些 java 书籍比较垃圾,只会照抄最原始的编程方式。

实际上这种低级功能应该禁用。应该使用异步并发的 BeginRead、BeginWrite 方式,并且保证使用windows的 IOCP 能力。
谢谢指导,收益颇多。
仍有问题,为何我在tcpclient里找不到有任何事件,看楼下的兄台说,只有socket才能进行基于事件的编程吗?但我记得tcpclient是对socket的封装?
望指导。



TcpClinet 也好, Socket 也好,只是提供一个缓存给你。至于怎么读,同步读写,还是异步读写都要程序员自己实现。

详细可看 MSDN:
tcpclient: https://msdn.microsoft.com/zh-cn/library/system.net.sockets.tcpclient(VS.80).aspx
socket: https://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket(v=vs.110).aspx

附,如果你对网络不是很熟悉,还是用 tcpclient 吧,简单些。。

#7


tcplistener/tcpclient 不是基于事件而设计,它输出 NetworkStream,而这个 Stream 可以使用 BeginRead、BeginWrite 来异步操作(异步回调)。

虽然 tcpclient/tcplistener 内部可以返回 socket 对象,但是它重构了底层代码,它直接支持 IOCP。而Socket 类并不自动支持 IOCP,是与 linux 系列兼容的设计。

所以你应该尽量使用 TcpListener/Tcpclient 类以及 NetworkStream,尽量不要使用 Socket 类。

#8


所谓“对socket的封装”这是一个模糊的说法。接口上的封装,往往是底层有重写。

有些人脑子里的“封装”就是旧瓶装新酒式的概念,他不理解软件上的封装的含义是重写底层。放到他那里就把封装说成了高级的东西是简单拼凑低级东西了。

有没有一种高级的东西是简单拼凑低级的东西?有很多。

但是 TcpListener/TcpClient 不是这类“封装”概念,其底层与 Socket 的底层有很大的不同。

#9


引用 8 楼 sp1234 的回复:
所谓“对socket的封装”这是一个模糊的说法。接口上的封装,往往是底层有重写。

有些人脑子里的“封装”就是旧瓶装新酒式的概念,他不理解软件上的封装的含义是重写底层。放到他那里就把封装说成了高级的东西是简单拼凑低级东西了。

有没有一种高级的东西是简单拼凑低级的东西?有很多。

但是 TcpListener/TcpClient 不是这类“封装”概念,其底层与 Socket 的底层有很大的不同。


为什么封装是重写底层呢,能稍微展开解释下吗?

#10


引用 9 楼 Seilboy 的回复:
Quote: 引用 8 楼 sp1234 的回复:

所谓“对socket的封装”这是一个模糊的说法。接口上的封装,往往是底层有重写。

有些人脑子里的“封装”就是旧瓶装新酒式的概念,他不理解软件上的封装的含义是重写底层。放到他那里就把封装说成了高级的东西是简单拼凑低级东西了。

有没有一种高级的东西是简单拼凑低级的东西?有很多。

但是 TcpListener/TcpClient 不是这类“封装”概念,其底层与 Socket 的底层有很大的不同。


为什么封装是重写底层呢,能稍微展开解释下吗?



不要想太多, TcpClient 就是调用 Socket 的。
无论是看直接源代码还是运行时代码跟踪,结果都一样。。