Hello StackOverFlow社区,我正在开发一个C#程序,它取决于同一服务器的许多套接字连接。
我想在我的连接类上进行多线程处理,这样我就可以创建尽可能多的连接,而无需创建多个类。
但是Code会解释它的具体情况:
网关(连接线程)
using SilkroadSecurityApi;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
namespace ConsoleLogin1
{
public class Gateway
{
public static MainClass MainWindow;
public static ServerEnum Server = ServerEnum.None;
public static List<Packet> GatewayPackets = new List<Packet>();
public static TransferBuffer GatewayRecvBuffer = new TransferBuffer(0x1000, 0, 0);
public static Security GatewaySecurity = new Security();
public static Socket GatewaySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static Thread loop;
public enum ServerEnum
{
None,
Gateway,
Agent
}
public void Gateway_thread()
{
while (true)
{
SocketError success;
byte[] bytes;
GatewayRecvBuffer.Size = GatewaySocket.Receive(GatewayRecvBuffer.Buffer, 0, GatewayRecvBuffer.Buffer.Length, SocketFlags.None, out success);
if (success != SocketError.Success)
{
if (success != SocketError.WouldBlock)
{
return;
}
}
else if (GatewayRecvBuffer.Size > 0)
{
GatewaySecurity.Recv(GatewayRecvBuffer);
}
else
{
return;
}
List<Packet> collection = GatewaySecurity.TransferIncoming();
if (collection != null)
{
GatewayPackets.AddRange(collection);
}
if (GatewayPackets.Count > 0)
{
foreach (Packet packet in GatewayPackets)
{
//incoming packets
}
GatewayPackets.Clear();
}
List<KeyValuePair<TransferBuffer, Packet>> list2 = GatewaySecurity.TransferOutgoing();
if (list2 != null)
{
foreach (KeyValuePair<TransferBuffer, Packet> pair in list2)
{
TransferBuffer key = pair.Key;
Packet packet = pair.Value;
success = SocketError.Success;
while (key.Offset != key.Size)
{
int num19 = GatewaySocket.Send(key.Buffer, key.Offset, key.Size - key.Offset, SocketFlags.None, out success);
if ((success != SocketError.Success) && (success != SocketError.WouldBlock))
{
break;
}
key.Offset += num19;
Thread.Sleep(1);
}
if (success != SocketError.Success)
{
break;
}
bytes = packet.GetBytes();
}
if (success != SocketError.Success)
{
return;
}
}
Thread.Sleep(1);
}
}
public static void SendToServer(Packet packet)
{
GatewaySecurity.Send(packet);
}
public void Connect(string IP, string Port)
{
loop = new Thread(new ThreadStart(this.Gateway_thread));
GatewaySocket.Connect(IP, int.Parse(Port));
loop.Start();
GatewaySocket.Blocking = false;
GatewaySocket.NoDelay = true;
}
}
}
主类
using System;
using System.Threading.Tasks;
using SilkroadSecurityApi;
using System.Threading;
namespace ConsoleLogin1
{
public class MainClass
{
public string ip = "25.122.17.189";
public string port = "15779";
public string locale = "22";
public string version = "190";
static void Main(string[] args)
{
new MainClass().Start();
}
public void Start()
{
Gateway.MainWindow = this;
new Gateway().Connect(ip, port);
}
}
}
但是我尝试了很多方法,例如:
Gateway G1 = new Gateway();
Gateway G2 = new Gateway();
也开始新线程
Thread G1 = new Thread(new ThreadStart(Gateway.Connect))
Thread G2 = new Thread(new ThreadStart(Gateway.Connect))
但是没有办法,在已经打开连接的情况下,无法创建新的GatewaySocket。 无论如何,我的问题是:我如何为Gateway做多线程,每个人都有自己的连接?
提前致谢。
答案 0 :(得分:0)
所以我会这样做:
我会定义各种类:
Connection类:
public class Connection
{
public string ip = "";
public string port = "";
public bool listening = false;
public TcpClient tcpClient;
private BackgroundWorker bw = new BackgroundWorker();
private NetworkStream stream;
public delegate DataReceivedEvent(Byte[] data, TcpEventArgs e);
public DataReceivedEvent dataReceived;
public List<Command> commands = new List<Command>();
//for Debugging purpose
public string lastError = "";
public Connection(string ip, string port)
{
this.ip = ip;
this.port = port;
bw.WorkerSupportsCancellation = true;
if(!Connect())
{
return;
//maybe do something here?
}
}
public bool Connect()
{
try
{
tcpClient.Connect(ip, port);
stream = tcpClient.GetStream();
return true;
}
catch(Exception ex)
{
lastError = ex.Message + " - " + ex.StackTrace;
return false;
}
}
public void BeginListening()
{
bw.DoWork += listenToNetwork();
bw.RunWorkerAsync();
}
public void EndListening()
{
bw.CancelAsync();
}
private void listenToNetwork(Object sender, DoWorkEventArgs e)
{
while(!PendingCancellation)
{
Byte[] bytes = new Byte[preferedLenghth];
listening = true;
Int32 bytesRead = stream.Read(bytes, 0, bytes.Length);
if(dataReceived != null)
{
dataReceived(bytes, new TcpEventArgs(bytesRead));
}
}
listening = false;
}
public void SendCommands()
{
foreach(Command cmd in commands)
{
cmd.Execute(ref stream);
}
}
}
Command类:
// i made a seperate class of Command because it is easy to expand without getting monsterclasse
public class Command
{
private CommandEnum cmd;
public Command(CommandEnum cmd)
{
this.cmd = cmd;
}
public void Execute(ref NetworkStream stream)
{
switch(cmd)
{
//insert commands like stream.write(bytesToSend, 0, bytesToSend.Length);
default:
break;
}
}
}
ActionController类:
public ActionController
{
public Connection conn;
public ActionController(string ip, string port)
{
conn = new Connection(ip, port)
conn.dataReceived += dataReceivedevent;
}
public void dataReceivedevent(Byte[] data, TcpEventArgs e)
{
//Do something with the received data here
}
//Do everything here! the Controller is here to provide necessary information for the GUI
}
.5 GUI取决于你的想象力;)
我认为代码是一种不言自明的问题,如果有什么不清楚的话