2012-09-05 24 views
2

我不知道,如果标题是所有信息。C#连接两个TCP套接字一起

我试图找到/写一个套接字服务器将接受来自客户端(远程登录)的连接,然后代表客户端连接的,连接到网络内四个Telnet服务器中的一个。

一旦连接上我保持多少个连接有一个计数器,然后如果有4个总连接,不允许任何新的连接,直到一四是可用的。

我写了这个:

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()); 

       } 
      } 
     } 
    } 
} 
} 

我已经多次改变了这个例子,所以我真的不知道了我有什么,并没有尝试过。我愿意尝试任何事情。

的目的实际上是运行这个允许一个telnet端口打开穿过防火墙,并允许连接到运行Telnet化石司机BBS软件DOS机器的小型网络。我只想将telnet流量重定向到仅使用一个端口的可用系统。

的问题是,我无法弄清楚如何真正将两个插座连接在一起,它们之间传递数据,因为它发生。传入的套接字和我代表服务器创建的套接字创建到服务器。

谢谢。

UPDATE:

这是为我工作,我还在找过的错误,但它的工作至今。

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--; 
    } 
} 
} 
+0

之间传递数据是什么你遇到的问题是什么?如果我们不知道确切的问题,我们不能帮助... –

+0

对不起,更新了包含的问题。 – user1270029

回答

5

我想,你可以创建类似如下的一类,以两个流

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); 
     } 
    } 
} 
+0

谢谢,是的,它现在传递数据。在进行几个屏幕的数据调试时,出现了''mscorlib.dll'中发生'System.OutOfMemoryException'类型的未处理异常。我会标记回答,因为它确实解决了问题。 – user1270029

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); 
     } 
    }