前言
本文主要介紹TCP、Sokcket和SuperSocket的基礎使用。
創建實例模式的SuperSocket服務
首先創建控制台項目,然后Nuget添加引用SuperSocket.Engine。

然后編寫服務代碼,SuperSocket的服務代碼主要是配置AppServer對象,因為AppServer已經很好的封裝端口監聽了。
代碼如下所示:
class Program
{
static AppServer appServer { get; set; }
static void Main(string[] args)
{
var serverConfig = new SuperSocket.SocketBase.Config.ServerConfig();
serverConfig.Port = 5180;
serverConfig.TextEncoding = "gb2312";
serverConfig.MaxConnectionNumber = 1000;
appServer = new AppServer();
//配置
if (!appServer.Setup(serverConfig))
{
Console.WriteLine("配置失敗!");
return;
}
//啟動
if (!appServer.Start())
{
Console.WriteLine("啟動失敗!");
return;
}
Console.WriteLine("啟動成功,按Q退出!");
appServer.NewSessionConnected += new SessionHandler<AppSession>(appServer_NewSessionConnected);
appServer.SessionClosed += appServer_NewSessionClosed;
appServer.NewRequestReceived += new RequestHandler<AppSession, StringRequestInfo>(appServer_NewRequestReceived);
while (Console.ReadKey().KeyChar != 'q')
{
continue;
}
//停止
appServer.Stop();
Console.WriteLine("服務已停止");
Console.ReadKey();
}
static void appServer_NewSessionConnected(AppSession session)
{
var count = appServer.SessionCount;
Console.WriteLine($"服務端得到來自客戶端的連接成功 ,當前會話數量:" + count);
//這里也可以向會話的stream里寫入數據,如果在這里向流寫入數據,則客戶端需要在Send之前先接收一次,不然的話,Send后接收的就是這條數據了
session.Send("連接成功");
}
static void appServer_NewSessionClosed(AppSession session, CloseReason aaa)
{
var count = appServer.SessionCount;
Console.WriteLine($"服務端 失去 來自客戶端的連接" + session.SessionID + aaa.ToString()+ " 當前會話數量:" + count);
}
static void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
{
Console.WriteLine($"Key:" + requestInfo.Key + $" Body:" + requestInfo.Body);
session.Send("我是返回值:" + requestInfo.Body);
}
}
AppServer:AppServer是SuperSocket中定義的Socket服務類,他替我們實現了復雜的端口監聽,不用再寫While循環,不用再關心線程阻塞的問題,在監聽端口在這里,我們只要調用AppServer的對象的Start方法,就可以了;AppServer還提供了一個配置文件類—ServerConfig,通過它,我們可以配置具體監聽的端口、並發數量、編碼、最大傳輸字節數、傳輸模式(TCP/UDP)等等屬性;此外還提供三個重要事件:會話連接啟動事件(NewSessionConnected)、會話關閉事件(SessionClosed)、請求接受事件(NewRequestReceived)。
注:文中在連接成功的事件中,我們向客戶端發送消息了,即,客戶端在連接后,發送消息前,需要接收該信息。
創建TCP發送消息客戶端
服務建立后,我們建立客戶端。
代碼如下所示:
static void Main(string[] args)
{
TCPConnect("127.0.0.1", 5180);
Console.ReadKey();
}
static void TCPConnect(String server, Int32 port)
{
string message = $"ADD kiba518 518" + "\r\n";
try
{
TcpClient client = new TcpClient();
client.Connect(server, port);
Byte[] data = System.Text.Encoding.Default.GetBytes(message);
String responseData = String.Empty;
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024 * 1024 * 2];
Int32 bytes = stream.Read(buffer, 0, buffer.Length);
responseData = System.Text.Encoding.Default.GetString(buffer, 0, bytes);
Console.WriteLine("接收服務器在連接事件中寫入的數據: {0}", responseData);
stream.Write(data, 0, data.Length);
Console.WriteLine("發送數據: {0}", message);
data = new Byte[256];
bytes = stream.Read(buffer, 0, buffer.Length);
responseData = System.Text.Encoding.Default.GetString(buffer, 0, bytes);
Console.WriteLine("接收返回值: {0}", responseData);
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e.Message);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e.Message);
}
Console.Read();
}
代碼很簡單,就是使用TcpClient連接服務器的IP和端口,然后發送消息。
因為我們使用的SuperSocket,有格式要求,所以我們需要准守。
格式要求如下:
命令名稱+空格+參數+參數+...參數+"\r\n"
對應的字符串如下:
$"ADD kiba518 518" + "\r\n"
因為上文中,服務在連接成功后就向客戶端發送的流中寫入了數據,所以,我們在Send消息前,先接收一下流中的數據。
客戶端與服務聯調
先運行服務,在運行客戶端,結果服務端與客戶端成功的完成了一次通信,如下圖所示:

為了更清晰的了解通信內容,我們在服務接收消息事件中斷點,如下圖:

可以看到參數requestInfo完整的解析了我們發送的字符串【"ADD kiba518 518" + "\r\n"】。
創建配置模式的SuperSocket服務
現在我們創建一個配置模式的SuperSocket服務,這種模式客戶通過配置創建多個SuperSocket,即可以在一個項目里通過配置監聽多個端口,這里,我們只做一個端口監聽的配置例子。
與實例模式的開始一樣,先創建一個控制台程序,然后Nuget添加引用SuperSocket.Engine。
然后進行三步操作。
一,編寫Main函數,啟動SuperSocket,通過啟動引導工廠BootstrapFactory實例化一個啟動引導對象,然后初始化化,該初始化會遍歷當前項目中所有繼承了AppServer的類,然后調用他們的Start方法,代碼如下所示:
static void Main(string[] args)
{
#region 初始化Socket
IBootstrap bootstrap = BootstrapFactory.CreateBootstrap();
if (!bootstrap.Initialize())
{
Console.WriteLine(DateTime.Now + ":Socket初始化失敗\r\n");
return;
}
var result = bootstrap.Start();
foreach (var server in bootstrap.AppServers)
{
if (server.State == ServerState.Running)
{
Console.WriteLine(DateTime.Now + ":serverName為:" + server.Name + "Socket運行中\r\n");
}
else
{
Console.WriteLine(DateTime.Now + ":serverName為:" + server.Name + "Socket啟動失敗\r\n");
}
}
Console.ReadKey();
#endregion
}
二,修改App.config配置文件,在configuration節點下,增加superSocket的section,並配置superSocket,代碼如下:
<configSections>
<section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
</configSections>
<!--配置SocketServer路徑-->
<superSocket>
<servers>
<!-- serverType屬性有兩個參數,第一個是服務類的完全限定名,第二個是服務類的命名空間 -->
<server name="MySocket" textEncoding="gb2312"
serverType="SuperSocketServerSessionMode.SocketServer, SuperSocketServerSessionMode"
ip="Any" port="5180" maxConnectionNumber="100">
</server>
</servers>
</superSocket>
三,創建SocketServer類、SocketSession類、SocketCommand類。
SocketServer類:繼承泛型AppServer(其泛型類指定一個會話類)該類用於創建SuperSocket的服務並監聽端口;其Setup方法,默認讀取App.config配置文件中的superSocket節點—servers節點—server節點;讀取時根據server的serverType屬性匹配讀取。
public class SocketServer : AppServer<SocketSession>
{
protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
{
Console.WriteLine("正在准備配置文件");
return base.Setup(rootConfig, config);
}
protected override void OnStarted()
{
Console.WriteLine("服務已開始");
base.OnStarted();
}
protected override void OnStopped()
{
Console.WriteLine("服務已停止");
base.OnStopped();
}
protected override void OnNewSessionConnected(SocketSession session)
{
Console.WriteLine("新的連接地址為" + session.LocalEndPoint.Address.ToString() + ",時間為" + DateTime.Now);
base.OnNewSessionConnected(session);
}
}
SocketSession類:繼承AppSession,是SuperSocket的會話類。
如果客戶端所發送的消息不合法,則會被會話的HandleUnknownRequest函數截獲,如果合法,則發送到指定的命令類中。
代碼如下:
public class SocketSession : AppSession<SocketSession>
{
public override void Send(string message)
{
Console.WriteLine("發送消息:" + message);
base.Send(message);
}
protected override void OnSessionStarted()
{
Console.WriteLine("Session已啟動");
base.OnSessionStarted();
}
protected override void OnInit()
{
this.Charset = Encoding.GetEncoding("gb2312");
base.OnInit();
}
protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
Console.WriteLine($"遇到未知的請求 Key:" + requestInfo.Key + $" Body:" + requestInfo.Body);
base.HandleUnknownRequest(requestInfo);
}
}
SocketCommand類:是SuperSocket的命令類,定義明確的會話命令;類名即客戶端發送消息的第一個空格前的字符串。
代碼如下:
public class SocketCommand : CommandBase<SocketSession, StringRequestInfo>
{
public override void ExecuteCommand(SocketSession session, StringRequestInfo requestInfo)
{
//根據參數個數或者其他條件判斷,來進行一些自己的操作
Console.WriteLine($"調用成功 Key:" + requestInfo.Key + $" Body:" + requestInfo.Body);
session.Send("已經成功接收到你的請求\r\n");
}
}
創建配置模式的SuperSocket客戶端
創建一個配置模式的SuperSocket客戶端,這一次我們使用Socket類創建。
代碼如下:
static Socket socketClient { get; set; }
static void Main(string[] args)
{
socketClient = new Socket(SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint point = new IPEndPoint(ip, 5180);
socketClient.Connect(point);
Thread thread = new Thread(Recive); //不停的接收服務器端發送的消息
thread.Start();
Thread thread2 = new Thread(Send);//不停的給服務器發送數據
thread2.Start();
}
static void Recive()
{
while (true)
{
//獲取發送過來的消息
byte[] buffer = new byte[1024 * 1024 * 2];
var effective = socketClient.Receive(buffer);
if (effective == 0)
{
break;
}
var str = Encoding.Default.GetString(buffer, 0, effective);
Console.WriteLine("服務器 --- " + str);
Thread.Sleep(2000);
}
}
static void Send()
{
int i = 0;int param1 = 0;int param2 = 0;
while (true)
{
i++;param1 = i + 1;param2 = i + 2;
Console.WriteLine($"Send i:{i} param1:{param1} param2:{param2}");
string msg = $"SocketCommand {param1} {param2}" + "\r\n";
Console.WriteLine($"msg:{msg}");
var buffter = Encoding.Default.GetBytes(msg);
var temp = socketClient.Send(buffter);
Console.WriteLine($"Send 發送的字節數:{temp} ");
Thread.Sleep(1000);
}
}
可以看到Socket的使用方式與Tcp的使用方式幾乎相同,都是指定IP和端口號,只是Socket多了一步,需要指定協議類型ProtocolType,這里我們指定了是TCP。
客戶端與服務聯調
先運行服務,在運行客戶端,結果通信成功,如下圖所示:

----------------------------------------------------------------------------------------------------
到此TCP、Sokcket和SuperSocket的基本使用已經介紹完了,代碼已經傳到Github上了,歡迎大家下載。
代碼已經傳到Github上了,歡迎大家下載。
Github地址: https://github.com/kiba518/SuperSocketConsole
----------------------------------------------------------------------------------------------------
注:此文章為原創,任何形式的轉載都請聯系作者獲得授權並注明出處!
若您覺得這篇文章還不錯,請點擊下方的【推薦】,非常感謝!
https://www.cnblogs.com/kiba/p/13728088.html

