3

タイトルがそれほど有益かどうかはわかりません。

クライアント(telnet)からの接続を受け入れ、接続されたクライアントに代わって、ネットワーク内の4つのtelnetサーバーの1つに接続するソケットサーバーを見つけて作成しようとしています。

接続したら、接続数のカウンターを保持します。合計4つの接続がある場合は、4つのうちの1つが使用可能になるまで、新しい接続を許可しません。

私はこれを書いた:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;

namespace ConsoleApplication1
{
class Program
{
    static int nodeCount = 4;
    static int currentNode = 1;

    static void Main(string[] args)
    {
        ServerProgram server = new ServerProgram();
    }

    class ServerProgram
    {
        private TcpListener tcpPrimaryListener;
        private Thread listenThread;

        public ServerProgram()
        {
            this.tcpPrimaryListener = new TcpListener(IPAddress.Any, 23);
            Console.WriteLine("Telnet BBS Port Concentrator Server Started.");
            Console.WriteLine("--------------------------------------------");

            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();
        }

        private void ListenForClients()
        {
            this.tcpPrimaryListener.Start();

            while (true)
            {
                TcpClient client = this.tcpPrimaryListener.AcceptTcpClient();
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
        }

        private void HandleClientComm(object client)
        {
            if (currentNode <= nodeCount)
            {
                Console.WriteLine("Connection thread created.");

                StreamWriter swStream;
                StreamWriter swStream2;
                StreamReader srStream;
                StreamReader srStream2;

                TcpClient tcpClient = (TcpClient)client;
                NetworkStream tcpClientStream = tcpClient.GetStream();

                TcpClient telnet = new TcpClient("192.168.100.5" + currentNode, 23);
                NetworkStream telnetStream = telnet.GetStream();

                currentNode++;

                while (true)
                {
                    srStream = new StreamReader(tcpClient.GetStream());
                    swStream2 = new StreamWriter(tcpClient.GetStream());

                    srStream2 = new StreamReader(telnet.GetStream());
                    swStream = new StreamWriter(telnet.GetStream());

                    swStream.Write(srStream.ReadToEnd());
                    swStream2.Write(srStream2.ReadToEnd());

                }
            }
        }
    }
}
}

私はこの例を何度も変更したので、自分が何を持っているのか、何を試したのか、もうよくわかりません。何でもやってみたいです。

目的は、実際にこれを実行して、ファイアウォールを介して1つのTelnetポートを開き、Telnet化石ドライバーBBSソフトウェアを実行しているDOSマシンの小さなネットワークへの接続を許可することです。1つのポートのみを使用してtelnetトラフィックを利用可能なシステムにリダイレクトしたいと思います。

問題は、2つのソケットを実際に接続して、それらの間でデータを渡す方法がわからないことです。着信ソケットと、サーバーに代わってサーバーに作成したソケット。

ありがとう。

アップデート:

これは私のために働いているものです、私はまだバグを探していますが、それは今のところ働いています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class Program
{
    static int nodeCount = 2;
    static int currentNode = 1;

    static void Main(string[] args)
    {
        ServerProgram server = new ServerProgram();
    }

    class ServerProgram
    {
        private TcpListener tcpPrimaryListener;
        private Thread listenThread;

        public ServerProgram()
        {
            this.tcpPrimaryListener = new TcpListener(IPAddress.Any, 23);
            Console.WriteLine("Telnet BBS Port Concentrator Server Started.");
            Console.WriteLine("--------------------------------------------");

            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();
        }

        private void ListenForClients()
        {
            this.tcpPrimaryListener.Start();

            while (true)
            {
                TcpClient client = this.tcpPrimaryListener.AcceptTcpClient();
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
        }

        private void HandleClientComm(object client)
        {
            string noNodes = "Sorry all nodes are occupied.";

            if (currentNode <= nodeCount)
            {
                Console.WriteLine("Client connected.");

                TcpClient tcpClient = (TcpClient)client;
                NetworkStream tcpClientStream = tcpClient.GetStream();

                TcpClient telnet = new TcpClient("10.24.9.11", 23);
                //TcpClient telnet = new TcpClient("192.168.100.5" + currentNode, 23);
                NetworkStream telnetStream = telnet.GetStream();

                currentNode++;

                ByPass linkedSockets = new ByPass(tcpClientStream, telnetStream);
            }
            else
            {
                TcpClient tcpClient = (TcpClient)client;
                NetworkStream tcpClientStream = tcpClient.GetStream();

                ASCIIEncoding encoder = new ASCIIEncoding();
                tcpClientStream.Write(Encoding.ASCII.GetBytes(noNodes), 0, noNodes.Length);
            }
        }
    }

    public class ByPass
    {
        public ByPass(Stream s1, Stream s2)
        {
            var cTokenSource = new CancellationTokenSource();
            var cToken = cTokenSource.Token;
            Task.Factory.StartNew(() => Process(s1, s2, cToken, cTokenSource), cToken);
            Task.Factory.StartNew(() => Process(s2, s1, cToken, cTokenSource), cToken);
            cToken.Register(() => cancelNotification());
        }

        public void Process(Stream s1, Stream s2, CancellationToken ct, CancellationTokenSource cTokenSource)
        {
            byte[] buf = new byte[0x10000];

            while (true)
            {
                if (ct.IsCancellationRequested)
                {
                    break;
                }

                try
                {
                    int len = s1.Read(buf, 0, buf.Length);
                    s2.Write(buf, 0, len);
                }
                catch
                {
                    s1.Close(); s2.Close();
                    cTokenSource.Cancel();
                    break;
                }
            }
        }
    }

    static void cancelNotification()
    {
        Console.WriteLine("Client disconnected.");
        currentNode--;
    }
}
}
4

2 に答える 2

6

以下のようなクラスを作成して、2つのストリーム間でデータを渡すことができると思います

public class ByPass
{
    public ByPass(Stream s1, Stream s2)
    {

        Task.Factory.StartNew(() => Process(s1, s2));
        Task.Factory.StartNew(() => Process(s2, s1));
    }

    public void Process(Stream sIn, Stream sOut)
    {
        byte[] buf = new byte[0x10000];
        while (true)
        {
            int len = sIn.Read(buf, 0, buf.Length);
            sOut.Write(buf, 0, len);
        }
    }
}
于 2012-09-05T18:39:12.363 に答える
0

私は少し変更を加えました、そしてそれは私の側で完璧に働きます

    public class StreamTransmitter
    {
        static TaskCompletionSource<bool> ts;

        public static async Task Start(Stream s1, Stream s2, CancellationToken token)
        {
            ts = new TaskCompletionSource<bool>();

            Process(s1, s2, token);
            Process(s2, s1, token);

            await ts.Task;
        }

        private static async Task Process(Stream sIn, Stream sOut, CancellationToken token)
        {
            byte[] buf = new byte[0x10000];
            int len = 0;
            do
            {
                len = await sIn.ReadAsync(buf, 0, buf.Length, token);
                await sOut.WriteAsync(buf, 0, len, token);
            }
            while (len > 0 && !token.IsCancellationRequested);

            ts.SetResult(true);
        }
    }
于 2018-02-12T12:31:38.317 に答える