1、方法介绍

BeginAccept(AsyncCallback callback, object state);

异步开始监听客户端连接。

  1. callback为一个委托,在成功接收客户端连接时调用委托方法。
  2. 向委托方法中传递的参数

**EndAccept (IAsyncResult result);**
结束监听客户端连接,一般在委托中成功接收连接后使用。
1. **result**:它存储此异步操作的状态信息以及任何用户定义数据。
返回。使用**result.AsyncState** 可以接收传递过来的参数。


**BeginReceive (byte[] buffer, int offset, int size, SocketFlags flag, AsyncCallback callback, object state);**
异步接收服务器发送来的数据
1. 存储接收的数据
2. 从buffer哪开始存储数据
3. 要接受最大的字节数
4. SocketFlags 值的按位组合
5. 接收成功后调用的委托方法
6. 要传递的参数

2、服务器端

namespace Tcp服务器端
{
class Program
{
/// <summary>
/// 接收客户端发送数据数组
/// </summary>
static byte[] data = new byte[1024]; static void Main(string[] args)
{
StartServerAsync();
} static void StartServerAsync()
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
serverSocket.Bind(point);
serverSocket.Listen(100); //异步监听客户端连接
serverSocket.BeginAccept(AcceptCallBack,serverSocket); Console.ReadKey();
}
/// <summary>
/// 接收到客户端连接时调用
/// </summary>
static void AcceptCallBack(IAsyncResult ar)
{
Console.WriteLine("一个客户端连接了进来\n");
Socket serverSocket = null;
try
{
//接收传递过来的main中的serverSocket
serverSocket = ar.AsyncState as Socket;
//结束接收,返回接收到的clientSocket
Socket clientSocket = serverSocket.EndAccept(ar); clientSocket.Send(Encoding.UTF8.GetBytes("你好呀。。。客户端"));
//异步开始监听客户端传递数据
clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //从头开始存,最大数量,none,接收到客户端后执行的回调函数,要传递的参数(会被传递给回调函数) //继续处理下一个客户端的连接,相当于一个伪递归
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
catch (Exception e)
{
Console.WriteLine(e);
if (serverSocket != null)
serverSocket.Close();
}
}
/// <summary>
/// 接收到客户端发送的数据时调用
/// </summary>
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar); //正常关闭的情况
if (count == 0)
{
Console.WriteLine("一个客户端正常断开了连接");
clientSocket.Close();
return;
}
Console.WriteLine("接收到数据:" + Encoding.UTF8.GetString(data, 0, count)); clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //从头开始存,最大数量,none,接收到客户端后执行的回调函数,要传递的参数
}
catch (Exception e)
{
//非正常关闭的情况
Console.WriteLine(e);
if (clientSocket != null)
clientSocket.Close();
}
} }
}

3、客户端

namespace Tcp客户端
{
class Program
{
static void Main(string[] args)
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
clientSocket.Connect(point); byte[] data = new byte[1024];
int length = clientSocket.Receive(data);
Console.WriteLine(Encoding.UTF8.GetString(data, 0, length)); //循环向服务器发送数据
while (true)
{
string s = Console.ReadLine();
//输入c正常退出,直接按×异常退出
if (s == "c")
{
clientSocket.Close();
return;
}
clientSocket.Send(Encoding.UTF8.GetBytes(s));
} Console.ReadKey(); }
}
}

4、效果

服务器可以接收多个客户端连接

多个客户端都可以向服务器发送数据

C#网络编程学习(4)---Socket Tcp进阶之 使用异步循环接收客户端连接和信息的更多相关文章

  1. Linux网络编程学习(十) ----- Socket(第六章)

    前言:由于第五章主要介绍了TCP和UDP协议以及两者的包头的字段以及相应的功能,这里就不介绍了,对着字段看功能就好了,后续开始学习第六章 1.Socket Socket实质上就是提供了通信的端点,每个 ...

  2. java 网络编程(五)----TCP进阶篇上传文本文件

    设计需求:从客户端上传txt文件到服务器,服务端收到文件后,发送消息给客户端接收完成. 1. 服务器端: public class UpLoadFileServer { public static v ...

  3. c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP  入门级客户端与服务端交互代码 网 ...

  4. 转 网络编程学习笔记一:Socket编程

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  5. Python学习笔记(四十五)网络编程(1)TCP编程

    摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014320043745 ...

  6. UNP(一):网络编程角度下的TCP、UDP协议

    此博文是学习UNP(UNIX Network Programming)后的读书笔记,供以后自己翻阅回想知识. TCP.UDP概述 在前面<计算机网络与TCP/IP>栏目下已经介绍过一些关于 ...

  7. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  8. 从零开始学Python第八周:网络编程基础(socket)

    Socket网络编程 一,Socket编程 (1)Socket方法介绍 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Soc ...

  9. Linux 网络编程四(socket多线程升级版)

    //网络编程--客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

随机推荐

  1. Java 实现 JS的eval函数

    JS的eval 函数, 给个表达式做参数, 返回表达式的值. Java的脚本引擎可以实现这个功能. 例子:   拼接一个字符串 \uxxxx, Unicode的十六进制编码, 然后把它打印出来. 即输 ...

  2. redis的缓存穿透 缓存并发 缓存失效

    我们在用缓存的时候,不管是Redis或者Memcached,基本上会通用遇到以下三个问题: 缓存穿透 缓存并发 缓存失效 一.缓存穿透 Paste_Image.png Paste_Image.png ...

  3. 【算法总结】Manacher's Algorithm

    Manacher's Algorithm针对的是最长回文子串问题.对于此问题,最直接的方法是遍历每一个元素,遍历过程中以每一个字符为中心向两边扩展以寻找此字符为中心的最长回文子串.复杂度O(n2).M ...

  4. windows下python使用虚拟环境

    官方文档: http://pythonguidecn.readthedocs.io/zh/latest/dev/virtualenvs.html virtualenv 是一个创建隔绝的Python环境 ...

  5. PRVF-0002 : could not retrieve local node name

    安装 oracle 的时候,./runInstaller 启动报错  PRVF-0002 : could not retrieve local node name 碰到这个错误是因为 OUT试图对你主 ...

  6. plsql developer v12.1的使用

    1.下载oracle客户端: 配置安装路径到PATH,我的是首先定义了一个环境变量ORACLE_CLIENT_PATH(这个路径其实就是官网下来的zip包解压缩后的路径),然后将这个变量附加到PATH ...

  7. tomcat启动加载web项目内存溢出

    通过tomcat命令启动tomcat的web项目时,根据项目大小,有可能会报以下两个错误. 在启动时没有错误,但是在访问时会报错: 1. java.lang.OutOfMemoryError: Jav ...

  8. POJ1365:素数

    Prime Land Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3552   Accepted: 1609 Descri ...

  9. Spring 3.1新特性之四:p命名空间设置注入(待补充)

    https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/ http://www.ibm.com/developerworks/cn/jav ...

  10. 四 Synchronized

    首先,一个问题:一个boolean成员变量,一个方法赋值,一个方法读值,多线程环境下,需要同步吗? 如果用同步的话,读也要用synchroized修饰,因为可见性的问题 需要同步,或者用volatil ...