簡體   English   中英

多線程套接字連接C#?

[英]Multithreading socket connections C#?

您好StackOverFlow社區,我正在研究一個C#程序,該程序依賴於同一服務器的許多套接字連接。
我想對連接類進行多線程處理,這樣我就可以創建所需數量的連接而無需創建多個類
但是,代碼會稍作解釋:
網關(連接線程)

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進行多線程處理,每個線程都有自己的連接?

提前致謝。

太好了,這就是我要怎么做:

  1. 我將定義各種類:

    • 連接
    • 命令
    • 動作控制器
    • 圖形用戶界面
  2. 連接類:

     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); } } } 
  3. 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; } } } 
  4. 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在您的想象中;)

我認為代碼是不言自明的,問是否不清楚

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM