使用WPF与C# 实现Telnet客户端

根据此来源:C#使用TcpClient实现telnet功能_rr白开水的博客-CSDN博客_c#实现telnet

此链接为转载,但是我找不着原来的了。

在这代码基础上进行更改

先来看看页面

1. 点击连接进行数据连接

2.中间文本框是显示服务端那边传过来的字符,可自己输入端口信息,只要把组件名绑定就好

wpf代码,可以不和我这个一样,自己爱怎么摆怎么摆,主意命名就行:

<Window x:Class="MinimalisticTelnet.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Telnet" Height="332" Width="397.75">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="111*"/>
            <ColumnDefinition Width="86*"/>
            <ColumnDefinition Width="170*"/>
            <ColumnDefinition Width="24*"/>
        </Grid.ColumnDefinitions>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="10.284,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Grid.Column="1" Grid.ColumnSpan="2"/>
        <TextBox HorizontalAlignment="Left" Height="24" Margin="10.284,41,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Grid.Column="1" Grid.ColumnSpan="2"/>
        <TextBlock HorizontalAlignment="Left" Margin="10,11,0,0" TextWrapping="Wrap" Text="主机名" VerticalAlignment="Top"/>
        <TextBlock HorizontalAlignment="Left" Margin="10,42,0,0" TextWrapping="Wrap" Text="端口" VerticalAlignment="Top"/>
        <TextBox x:Name="TBhostname" Height="23" Margin="10.284,10,40.5,0" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"/>
        <TextBox HorizontalAlignment="Left" Height="24" Margin="10.284,41,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Grid.Column="1" Grid.ColumnSpan="2"/>
        <TextBlock HorizontalAlignment="Left" Margin="10,99,0,0" TextWrapping="Wrap" Text="密码" VerticalAlignment="Top"/>
        <TextBlock HorizontalAlignment="Left" Margin="10,70,0,0" TextWrapping="Wrap" Text="用户名" VerticalAlignment="Top"/>
        <TextBox x:Name="TBusername" Height="24" Margin="10.284,70,40.5,0" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"/>
        <TextBox x:Name="TBpassword" Height="24" Margin="10.284,99,40.5,0" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"/>
        <TextBox x:Name="TBport" Height="24" Margin="10.284,41,40.5,0" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"/>
        <Button x:Name="TBConnect" Content="连接" HorizontalAlignment="Left" Margin="135.284,56,0,0" VerticalAlignment="Top" Width="50" Click="TBConnect_Click" Grid.Column="2" RenderTransformOrigin="1.221,0.447" Height="29" Grid.ColumnSpan="2"/>
        <Button x:Name="Btncommand" Content="命令" HorizontalAlignment="Left" Margin="141.284,0,0,10" Width="44" Click="TBConnect_Click" Grid.Column="2" Height="23" VerticalAlignment="Bottom" Grid.ColumnSpan="2"/>
        <TextBox x:Name="TBcommand" Margin="10,0,0,10" TextWrapping="Wrap" Grid.ColumnSpan="3" HorizontalAlignment="Left" Width="315" Height="23" VerticalAlignment="Bottom"/>
        <ListBox x:Name="TBListBox" Margin="10,128,10.716,40" SelectionChanged="TBwait1_SelectionChanged" FontWeight="Bold" FontSize="16" Grid.ColumnSpan="4" BorderThickness="0">
            <TextBlock x:Name="TBwait" TextWrapping="Wrap" Text="TextBlock"/>
        </ListBox>

    </Grid>
</Window>

 两个按钮,几个文本框,几个文本。

所有需要在C#代码里引用的我都做了命名前边加TB统一,例:TBhostname,TBport。

C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Net.Sockets;

namespace MinimalisticTelnet
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            TBwait.Visibility = Visibility.Collapsed;
            TBcommand.Visibility = Visibility.Collapsed;
            Btncommand.Visibility = Visibility.Collapsed;
        }
        TcpClient tcpSocket;
        private void TBConnect_Click(object sender, RoutedEventArgs e)
        {

            //获取当前点击的Button文本
            string btn = System.Convert.ToString((sender as Button).Content);

            if (btn == "连接")
            {
                //在端口上创建与主机名配对的新 Telnet 连接

                //远程连接ll
                tcpSocket = new TcpClient(TBhostname.Text, TBport.Text);

                //本地连接(下回做一个本地的服务端,搭配使用)
                //tcpSocket = new TcpClient("localhost", TBport.Text);

                //使用用户“root”登录,密码“rootpassword”,使用100ms的超时, 
                //并显示服务器输出
                string s = Login(TBusername.Text, TBpassword.Text, 100);
                TBwait.Text = s;
                TBwait.Visibility = Visibility.Visible;
                InitializeComponent();
                Console.Write(s);

                #region 如果是本地连接就不需这些,直接注释即可
                // 服务器输出应以“#”,否则连接失败
                //s.TrimEnd() 服务器返回的数据
                string prompt = s.TrimEnd();
                prompt = s.Substring(prompt.Length - 1, 1);
                if (prompt != "#")
                    throw new Exception("连接失败");

                prompt = "";
                #endregion

                TBcommand.Visibility = Visibility.Visible;
                Btncommand.Visibility = Visibility.Visible;
            }

            if (btn == "命令")
            {
            if (btn == "命令")
            {
                WriteLine(TBcommand.Text);
                string s = Read();
                TBwait.Text = s;
                TBcommand.Text = "";
                Console.Write(s + "\n");
            }
            }


            Console.WriteLine("******DISCONNECTED******");
            Console.ReadLine();
        }

        


        int TimeOutMs = 1 * 1000;


        public string Login(string Username, string Password, int LoginTimeOutMs)
        {
            int oldTimeOutMs = TimeOutMs;
            TimeOutMs = LoginTimeOutMs;
            //接收服务器输出数据
            string s = Read();
            Console.Write(s+"\n");

            #region 登录(如果是本地链接,不需要登录,可以把这段注释了)
            if (!s.TrimEnd().EndsWith(":"))
                throw new Exception("连接失败:无登录提示");
            //输入登录账号
            WriteLine(Username);

            s += Read();
            Console.Write(s + "\n");
            if (!s.TrimEnd().EndsWith(":"))
                throw new Exception("连接失败:无密码提示");
            //输入登录密码
            WriteLine(Password);
            s += Read();
            #endregion

            Console.Write(s + "\n");
            TimeOutMs = oldTimeOutMs;

            return s;
        }

        public void DisConnect()
        {
            if (tcpSocket != null)
            {
                if (tcpSocket.Connected)
                {
                    tcpSocket.Client.Disconnect(true);
                }
            }
        }

        public void WriteLine(string cmd)
        {
            Write(cmd + "\r\n");
        }

        public void Write(string cmd)
        {
            if (!tcpSocket.Connected) return;
            //转换成中文编码GB2312
            byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));
            //GetStream 返回一个可用来发送和接收数据的 NetworkStream
            tcpSocket.GetStream().Write(buf, 0, buf.Length);
        }

        //服务器输出
        //tcpSocket.Connected是否连接的上
        public string Read()
        {
            //未连接就返回null
            if (!tcpSocket.Connected) return null;
            StringBuilder sb = new StringBuilder();
            do
            {
                //解析远程登录
                ParseTelnet(sb);
                System.Threading.Thread.Sleep(TimeOutMs);
            } while (tcpSocket.Available > 0);

            return ConvertToGB2312(sb.ToString());
        }

        public bool IsConnected
        {
            get { return tcpSocket.Connected; }
        }

        //解析远程登录
        void ParseTelnet(StringBuilder sb)
        {
            //tcpSocket.Available 获取已经从网络接收且可供读取的数据量。
            while (tcpSocket.Available > 0)
            {
                //NetworkStream 异步读取 为网络访问提供数据的基础流。
                //返回用于发送和接收数据的 NetworkStream
                int input = tcpSocket.GetStream().ReadByte();
                switch (input)
                {
                    case -1:
                        break;
                    case (int)Verbs.IAC:
                        // 解释为命令
                        int inputverb = tcpSocket.GetStream().ReadByte();
                        if (inputverb == -1) break;
                        switch (inputverb)
                        {
                            case (int)Verbs.IAC:
                                //文本 IAC = 255 转义,因此将字符 255 附加到字符串
                                sb.Append(inputverb);
                                break;

                            case (int)Verbs.DO:
                            case (int)Verbs.DONT:
                            case (int)Verbs.WILL:
                            case (int)Verbs.WONT:
                                // 用“WONT”回复所有命令,除非它是 SGA(支持继续)
                                int inputoption = tcpSocket.GetStream().ReadByte();
                                if (inputoption == -1) break;
                                tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
                                if (inputoption == (int)Options.SGA)
                                    tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL : (byte)Verbs.DO);
                                else
                                    tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
                                tcpSocket.GetStream().WriteByte((byte)inputoption);
                                break;
                            default:
                                break;
                        }
                        break;
                    default:
                        sb.Append((char)input);
                        break;
                }
            }
        }

        //格式更改
        private string ConvertToGB2312(string str_origin)
        {
            char[] chars = str_origin.ToCharArray();
            byte[] bytes = new byte[chars.Length];
            for (int i = 0; i < chars.Length; i++)
            {
                int c = (int)chars[i];
                bytes[i] = (byte)c;
            }
            Encoding Encoding_GB2312 = Encoding.GetEncoding("GB2312");
            string str_converted = Encoding_GB2312.GetString(bytes);
            return str_converted;
        }

        private void TBwait1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }


    }
    enum Verbs
    {
        WILL = 251,
        WONT = 252,
        DO = 253,
        DONT = 254,
        IAC = 255
    }

    enum Options
    {
        RD = 1,
        SGA = 3
    }

}


已经找不着最开始哪出来的,但是转载的找到了一个:

C#使用TcpClient实现telnet功能_rr白开水的博客-CSDN博客_c#实现telnet

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值