using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms; namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listener = new TcpListener(IPAddress.Any, );// 端口根据需要确定
listener.Start(); // 后台线程1:用于接收tcp连接请求,并将网络流加入列表。随主线程的退出而退出。
new Thread(() =>
{
while (true)
{
Thread.Sleep();// 可以根据需要设置时间
if (!listener.Pending())
{
continue;
}
var client = listener.AcceptTcpClient();
// 下面属性根据需要进行设置
// client.ReceiveBufferSize
// client.ReceiveTimeout
// client.SendBufferSize
// client.SendTimeout
if (!client.Connected)
{
continue;
}
streams.Add(client.GetStream());
}
}) { IsBackground = true }.Start(); // 后台线程2:用于接收请求,并作出响应。随主线程的退出而退出。
new Thread(() =>
{
while (true)
{
Thread.Sleep();// 可以根据需要设置时间
if (streams == null || streams.Count == )
{
continue;
}
streams = streams.Where(s => s.CanRead && s.CanWrite).ToList();
foreach (var stream in streams.Where(stream => stream.CanRead && stream.CanWrite))
{
AsyncReceiveBytes(stream,
s =>
{
// todo:对result进行解码
// todo:对收到指令进行逻辑判断,得出待响应的C#对象
AsyncSendBytes(s, new byte[]); // todo:将待响应的C#对象转换成字节数组,替换new byte[0]。
});
}
}
}) { IsBackground = true }.Start();
} // 发送事件和目标的入口
public void SendEventAndTarget()
{
if (streams == null || streams.Count == )
{
return;
}
streams = streams.Where(s => s.CanRead && s.CanWrite).ToList();
foreach (var stream in streams.TakeWhile(stream => stream.CanWrite))
{
AsyncSendBytes(stream, new byte[]);// todo:这里将待发送的C#对象转换的字节数组替换new byte[0]。
}
} private static void AsyncReceiveBytes(NetworkStream stream,
Action<NetworkStream> callback)
{
// 短时后台线程:用于处理网络流的读操作,处理完成后即归还线程池。
// 每个网络流都会分配一个线程。
//ThreadPool.SetMaxThreads();根据需要设置。
ThreadPool.QueueUserWorkItem(delegate
{
var buffer = new byte[];// 1024:根据需要进行设置。
var result = new byte[];
do
{
var a = stream.Read(buffer, , buffer.Length);
result = result.Concat(buffer.Take(a)).ToArray();
} while (stream.DataAvailable);
callback(stream);
});
}
private static void AsyncSendBytes(NetworkStream stream, byte[] bytes)
{
// 短时后台线程:用于处理网络流的写操作,处理完成后即归还线程池。
// 每个网络流都会分配一个线程。
//ThreadPool.SetMaxThreads();根据需要设置。
ThreadPool.QueueUserWorkItem(delegate
{
try
{
stream.Write(bytes, , bytes.Count());
}
catch (Exception)
{
MessageBox.Show("远程主机主动断开此连接!");// 也可以做其它处理。
}
});
} private readonly TcpListener listener;
// 网络流列表
private List<NetworkStream> streams = new List<NetworkStream>();
}
}

找时间在项目中应用后,再总结一下。

C# TcpListener的编程要点的更多相关文章

  1. Java 编程要点之并发(Concurrency)详解

    计算机用户想当然地认为他们的系统在一个时间可以做多件事.他们认为,他们可以工作在一个字处理器,而其他应用程序在下载文件,管理打印队列和音频流.即使是单一的应用程序通常也是被期望在一个时间来做多件事.例 ...

  2. [.NET] 《Effective C#》快速笔记 - C# 高效编程要点补充

    <Effective C#>快速笔记 - C# 高效编程要点补充 目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 ...

  3. 【转载】漫谈C++:良好的编程习惯与编程要点

    原文: 漫谈C++:良好的编程习惯与编程要点 阅读目录 以良好的方式编写C++ class Class with pointer member(s):记得写Big Three static与类 正文 ...

  4. 《Effective C#》快速笔记(六)- - C# 高效编程要点补充

    目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 四十九.实现与 CLS 兼容的程序集 五十.实现小尺寸.高内聚的程序集 这是 ...

  5. Blocks编程要点

    [老狼推荐]Blocks编程要点原文:Blocks Programming Topics链接:http://developer.apple.com/library/ios/#documentation ...

  6. VS2017 ATL创建ActiveX编程要点

    VS2017 ATL创建ActiveX控件编程要点: 一.创建vs项目需要安装器visual studio installer中: 安装 visual studio扩展开发中的 用于x86和x64的V ...

  7. Essential Java.《Java 编程要点》

    Essential Java.<Java 编程要点> Essential Java, is a book about the Essentials of Java Programming. ...

  8. 基础笔记(一):C#编程要点

    前言 来源于手中日常摘录的资料和书籍,算是对看过的东西的总结,部分注有阅读心得,也有部分只提出大纲或结论.(备注:本篇文章中大部分要点需要有实际的开发经验,有助于阅读理解.)     目录 const ...

  9. 漫谈C++:良好的编程习惯与编程要点

    以良好的方式编写C++ class 假设现在我们要实现一个复数类complex,在类的实现过程中探索良好的编程习惯. ① Header(头文件)中的防卫式声明 complex.h: # ifndef ...

随机推荐

  1. 启动hadoop报ERROR org.apache.hadoop.hdfs.server.namenode.FSImage: Failed to load image from FSImageFile

    不知道怎么回事,今天在启动集群时通过jps查看进程时始终有一个standby namenode进程无法启动.查看日志时报的是不能加载fsimage文件.日志截图如下: 日志报的很明显了是不能加载元数据 ...

  2. javascript回车完美实现tab切换功能

    javascript通过回车实现tab切换功能,最经有一个项目是给化工厂做的在使用的过程中需要输入大量的数据,使用的都是小键盘区,在以前都是通过excel录入数据的现在, 在网页上需要实现excel ...

  3. Google -We’re Sorry....

    Author:KillerLegend From:http://www.cnblogs.com/killerlegend/p/3734840.html Date:2014.5.18 一大清早 一大早起 ...

  4. Learning Scrapy笔记(一)- Scrapy简单介绍

    Scrapy简述 Scrapy十一个健壮的,用来从互联网上抓取数据的web框架,Scrapy只需要一个配置文件就能组合各种组件和配置选项,并且Scrapy是基于事件(event-based)的架构,使 ...

  5. uboot启动流程

    uboot 的启动过程及工作原理2.1 启动模式介绍    大多数 Boot Loader 都包含两种不同的操作模式:"启动加载"模式和"下载"模式,这种区别仅 ...

  6. Python学习教程(learning Python)--1.2.2 Python格式化输出基础

    本节讨论为何要格式化输出数据? 先看一段代码吧,本程序的功能是计算月支付金额. amount_due = 5000.0 #年支付金额 monthly_payment = amount_due / 12 ...

  7. openSUSE13.1安装搜狗输入法 for Linux

    一句话总结:爽死我了!什么叫输入的快感终于体会到了,搜狗输入法,码农的好伙伴!!! 转自openSUSE论坛 女王陛下 https://forum.suse.org.cn/viewtopic.php? ...

  8. 安装Mongodb3.0.6单实例

    [root@b28-17-51 ~]#mkdir -p /export/data [root@b28-17-51 ~]#mkdir -p /export/log [root@b28-17-51 exp ...

  9. GIS中栅格数据的拼接

    Datamanager Tools——Raster——Raster Dataset——Mosaic to New Raster 如果最大值是实际的真值,选择masaic operator要保留Max ...

  10. core java 1~4(HelloWorld & 标识符|关键字|数据类型 & 表达式|流程控制 & 数组)

    MODULE 1 Java的编译和运行----------------------------编译:javac -d bin src\HelloWorld.java -d:指定编译后的class 文件 ...