1

我正在尝试用 C# 编写一个简单的 TCP 网络隧道(使用 MonoDevelop,而不是 VS)。目前,它可以工作到我建立连接的地步。连接后netcat localhost <portnum>,我不断收到充满空值的数据包。我的代码是:

Tunnel.cs

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class Tunnel {
    public TcpListener listener;
    public NetworkStream local, remote;
    private Thread threadControl, threadLocalSide, threadRemoteSide;
    public Tunnel(int localPort, String remoteServer, int remotePort) {
        this.listener = new TcpListener(new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), localPort));
        this.remote = new TcpClient(remoteServer, remotePort).GetStream();
        this.threadControl = new Thread(new ThreadStart(this.thread));
        this.threadControl.Start();
    }
    public void thread() {
        this.listener.Start();
        Console.WriteLine("Awaiting connection...");
        this.local = this.listener.AcceptTcpClient().GetStream();
        Console.WriteLine("Tunnel connected!");
        Console.WriteLine("Starting threads...");
        this.threadLocalSide = new Thread(new ThreadStart(this.localSide));
        this.threadLocalSide.Start();
        this.threadRemoteSide = new Thread(new ThreadStart(this.remoteSide));
        this.threadRemoteSide.Start();
    }
    public void localSide() {
        byte[] buffer = new byte[2048];
        try {
            while(true) {
                while(!this.local.DataAvailable);
                this.local.Read(buffer, 0, buffer.Length);
                this.remote.Write(buffer, 0, buffer.Length);
            }
        } catch {
            this.threadRemoteSide.Abort();
        }
    }
    public void remoteSide() {
        byte[] buffer = new byte[2048];
        try {
            while(true) {
                while(!this.remote.DataAvailable);
                this.remote.Read(buffer, 0, buffer.Length);
                this.local.Write(buffer, 0, buffer.Length);
            }
        } catch {
            this.threadLocalSide.Abort();
        }
    }
}
4

1 回答 1

1

Stream.Read()方法返回实际接收的字节数,但您总是发送整个缓冲区。

尝试以这种方式将数据从一个流复制到另一个流:

static void CopyStream(Stream from, Stream to)
{
    var buffer = new byte[2048];
    while(true)
    {
        int bytesRead = from.Read(buffer, 0, buffer.Length);
        if(bytesRead == 0) break; // 0 means end of stream
        to.Write(buffer, 0, bytesRead);
    }
}

localSide() { CopyStream(local, remote); }
remoteSide() { CopyStream(remote, local); }
于 2013-08-18T17:13:43.730 回答