using System;
using NewLife;
using NewLife.Reflection;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using NewLife.Log;
using NewLife.Net;
using NewLife.Net.Application;
using NewLife.Net.DNS;
using NewLife.Net.Modbus;
using NewLife.Net.Proxy;
using NewLife.Net.Sockets;
using NewLife.Net.Stress;
using NewLife.Security;
using NewLife.Threading;
using NewLife.IO;
namespace Test2
{
class Program
{
static void Main(string[] args)
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
XTrace.UseConsole();
while (true)
{
#if !DEBUG
try
{
#endif
Test3();
#if !DEBUG
}
catch (Exception ex)
{
XTrace.WriteException(ex);
//Console.WriteLine(ex.ToString());
}
#endif
GC.Collect();
Console.WriteLine("OK!");
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key != ConsoleKey.C) break;
//Console.Clear();
}
}
private static void Test1()
{
AppTest.Start();
//AppTest.TcpConnectionTest();
//TcpStress.Main();
}
static void Test2()
{
var server = new NetServer();
server.Port = 88;
server.NewSession += server_NewSession;
//server.Received += server_Received;
server.SocketLog = null;
server.SessionLog = null;
server.Start();
var html = "新生命开发团队";
var sb = new StringBuilder();
sb.AppendLine("HTTP/1.1 200 OK");
sb.AppendLine("Server: NewLife.WebServer");
sb.AppendLine("Connection: keep-alive");
sb.AppendLine("Content-Type: text/html; charset=UTF-8");
sb.AppendFormat("Content-Length: {0}", Encoding.UTF8.GetByteCount(html));
sb.AppendLine();
sb.AppendLine();
sb.AppendLine();
sb.Append(html);
response = sb.ToString().GetBytes();
while (true)
{
Console.Title = "会话:{0:n0} 请求:{1:n0} 错误:{2:n0}".F(server.SessionCount, Request, Error);
Thread.Sleep(500);
}
}
static void server_NewSession(object sender, NetSessionEventArgs e)
{
var session = e.Session;
session.Received += session_Received;
session.Session.Error += (s, e2) => Error++;
}
static Int32 Request;
static Int32 Error;
static Byte[] response;
static void session_Received(object sender, ReceivedEventArgs e)
{
Request++;
var session = sender as INetSession;
//XTrace.WriteLine("客户端 {0} 收到:{1}", session, e.Stream.ToStr());
//XTrace.WriteLine(response.ToStr());
session.Send(response);
//session.Dispose();
}
static void Test3()
{
//var _server = new NetServer();
//var _server = new DNSServer();
var _server = new HttpProxy();
//_server.Port = 8888;
_server.Log = XTrace.Log;
_server.SocketLog = Logger.Null;
//_server.SessionLog = Logger.Null;
_server.SessionLog = XTrace.Log;
_server.Start();
while (true)
{
//var svr = _server.Servers[0] as TcpServer;
var svr = _server;
Console.Title = "会话数:{0} 连接:{1} 发送:{2} 接收:{3}".F(_server.SessionCount, svr.StatSession, svr.StatSend, svr.StatReceive);
Thread.Sleep(1000);
}
}
static UdpServer _udpServer;
static void Test5()
{
if (_udpServer != null) return;
_udpServer = new UdpServer();
_udpServer.Port = 888;
//_udpServer.Received += _udpServer_Received;
_udpServer.SessionTimeout = 5000;
_udpServer.Open();
var session = _udpServer.CreateSession(new IPEndPoint(IPAddress.Any, 0));
for (int i = 0; i < 5; i++)
{
var buf = session.Receive();
Console.WriteLine(buf.ToHex());
session.Send("Hello");
}
//Console.ReadKey();
_udpServer.Dispose();
_udpServer = null;
}
static void _udpServer_Received(object sender, ReceivedEventArgs e)
{
var session = sender as ISocketSession;
XTrace.WriteLine("{0} [{1}]:{2}", session.Remote, e.Stream.Length, e.Stream.ReadBytes().ToHex());
}
static void Test4()
{
//var proxy = new NATProxy("s3.peacemoon.cn", 3389);
var proxy = new NATProxy("192.168.0.85", 3389);
//proxy.Port = 89;
proxy.Local = "tcp://:89";
proxy.Log = XTrace.Log;
//proxy.SessionLog = XTrace.Log;
proxy.Start();
while (true)
{
Console.Title = "会话数:{0}".F(proxy.SessionCount);
Thread.Sleep(1000);
}
}
static Int32 success = 0;
static Int32 total = 0;
static void GetMac(Object state)
{
var ip = IPAddress.Parse("192.168.0." + state);
var mac = ip.GetMac();
if (mac != null)
{
success++;
Console.WriteLine("{0}\t{1}", ip, mac.ToHex("-"));
}
total++;
}
static void Test6()
{
// UDP没有客户端服务器之分。推荐使用NetUri指定服务器地址
var udp = new UdpServer();
udp.Remote = new NetUri("udp://smart.peacemoon.cn:7");
udp.Received += (s, e) =>
{
XTrace.WriteLine("收到:{0}", e.ToStr());
};
udp.Open();
udp.Send("新生命团队");
udp.Send("学无先后达者为师!");
// Tcp客户端会话。改用传统方式指定服务器地址
var tcp = new TcpSession();
tcp.Remote.Host = "smart.peacemoon.cn";
tcp.Remote.Port = 13;
tcp.Open();
var str = tcp.ReceiveString();
XTrace.WriteLine(str);
// 产品级客户端用法。直接根据NetUri创建相应客户端
var client = new NetUri("tcp://smart.peacemoon.cn:17").CreateRemote();
client.Received += (s, e) =>
{
XTrace.WriteLine("收到:{0}", e.ToStr());
};
client.Open();
Thread.Sleep(1000);
}
static void Test7()
{
//TestNewLife_Net test = new TestNewLife_Net();
//test.StartTest();
//test.StopTest();
}
private static void Test8()
{
XTrace.WriteLine("启动两个服务端");
// 不管是哪一种服务器用法,都具有相同的数据接收处理事件
var onReceive = new EventHandler<ReceivedEventArgs>((s, e) =>
{
// ReceivedEventArgs中标准使用Data+Length或Stream表示收到的数据,测试时使用ToStr/ToHex直接输出
// UserState表示来源地址IPEndPoint
XTrace.WriteLine("收到 {0}:{1}", e.UserState, e.ToStr());
// 拿到会话,原样发回去。
// 不管是TCP/UDP,都会有一个唯一的ISocketSession对象表示一个客户端会话
var session = s as ISocketSession;
session.Send(e.Stream);
});
// 入门级UDP服务器,直接收数据
var udp = new UdpServer(3388);
udp.Received += onReceive;
udp.Open();
// 入门级TCP服务器,先接收会话连接,然后每个连接再分开接收数据
var tcp = new TcpServer(3388);
tcp.NewSession += (s, e) =>
{
XTrace.WriteLine("新连接 {0}", e.Session);
e.Session.Received += onReceive;
};
tcp.Start();
// 轻量级应用服务器(不建议作为产品级使用),同时在TCP/TCPv6/UDP/UDPv6监听指定端口,统一事件接收数据
var svr = new NetServer();
svr.Port = 3377;
svr.Received += onReceive;
svr.Start();
Console.WriteLine();
// 构造多个客户端连接上面的服务端
var uri1 = new NetUri(ProtocolType.Udp, IPAddress.Loopback, 3388);
var uri2 = new NetUri(ProtocolType.Tcp, IPAddress.Loopback, 3388);
var uri3 = new NetUri(ProtocolType.Tcp, IPAddress.IPv6Loopback, 3377);
var clients = new ISocketClient[] { uri1.CreateRemote(), uri2.CreateRemote(), uri3.CreateRemote() };
// 打开每个客户端,如果是TCP,此时连接服务器。
// 这一步也可以省略,首次收发数据时也会自动打开连接
// TCP客户端设置AutoReconnect指定断线自动重连次数,默认3次。
foreach (var item in clients)
{
item.Open();
}
Thread.Sleep(1000);
Console.WriteLine();
XTrace.WriteLine("以下灰色日志为客户端日志,其它颜色为服务端日志,可通过线程ID区分");
// 循环发送几次数据
for (int i = 0; i < 3; i++)
{
foreach (var item in clients)
{
item.Send("第{0}次{1}发送".F(i + 1, item.Remote.ProtocolType));
var str = item.ReceiveString();
Trace.Assert(!str.IsNullOrEmpty());
}
Thread.Sleep(500);
}
XTrace.WriteLine("不用担心断开连接等日志,因为离开当前函数后,客户端连接将会被销毁");
// 为了统一TCP/UDP架构,网络库底层(UdpServer/TcpServer)是重量级封装为ISocketServer
// 实际产品级项目不关心底层,而是继承中间层(位于NewLife.Net)的NetServer/NetSession,直接操作ISocketSession
// 平台级项目一般在中间层之上封装消息序列化,转化为消息收发或者RPC调用,无视网络层的存在
// 以太网接口之上还有一层传输接口ITransport,它定义包括以太网和其它工业网络接口的基本数据收发能力
}
static void svr_Received(object sender, ReceivedEventArgs e)
{
XTrace.WriteLine(e.ToStr());
}
}
}
|