C#SOCKET通信に基づくTelnetシミュレーションツール


最近、ネット上の通信プロトコルを振り回して、プロトコルに慣れるたびにtelnetでテストするのに慣れていますが、テストの過程で、悩んでいるのは、入力できないところがあることです.
エラーは、エラーが発生すると再入力され、CMDコマンドのように方向キーで前の入力に戻ることはできません.何度も苦しんだ後、Telnetのような機能を作ることにしました.
シミュレーションツールは、より正確にはSOCKETベースのネットワーク通信ツールであり、SMTP/POP 3/IMAPのテストをよりよく行うことができる.実装されているキーコードは次のとおりです.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using UtilSp.ClassLib;
using System.Linq.Expressions;
using System.Threading;

namespace SocketLink
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private Socket socket_ = null;
        private Helper helper_ = new Helper();//In order to automatically update data to UI with binding property.
        private int receiveLen_max_ = 0xFFFF;
        private Thread receiveThread_ = null;
        private Encoding receiveEncoding_ = Encoding.UTF8;
        private bool needConvertBase64Received_ = false;
        private string lineBreak_ = "\r
"; private void buttonConnect_Click(object sender, EventArgs e) { try { string host = textBoxHost.Text; string port = textBoxPort.Text; if (string.IsNullOrEmpty(host)) { showMessage(Tip.hostEmpty); return; } if (string.IsNullOrEmpty(port)) { showMessage(Tip.portEmpty); return; } if (!IpPortSp.isPort(port)) { MessageBox.Show(Tip.portIllegal); return; } socket_ = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket_.Connect(host, Convert.ToInt32(port)); if (!socket_.Connected) { showBackInfo(Tip.connectFail); return; } receiveThread_ = new Thread(receiveCallBack);//Create thread to listen receive from socket. receiveThread_.IsBackground = true; receiveThread_.Start(); helper_.connectEnabled_pro = false; helper_.disconnectEnabled_pro = true; helper_.sendEnabled_pro = true; showBackInfo(Tip.connectOK); } catch (System.Exception ex) { showBackInfo(ex.Message); } } private void showMessage(string message) { MessageBox.Show(message); } private void showBackInfo(string backInfo, bool isNeedInvoke = false) { if (isNeedInvoke) { this.Invoke((Action)(() => { helper_.backInfo_pro += backInfo + "\r
"; })); } else { helper_.backInfo_pro += backInfo + "\r
"; } } public class Helper : INotifyPropertyChanged //Automatically update UI data class { #region backInfo Property private string backInfo_ = ""; public string backInfo_pro { get { return backInfo_; } set { if (value == backInfo_) { return; } backInfo_ = value; NotifyPropertyChanged(() => backInfo_pro); } } #endregion #region connectEnabled Property private bool connectEnabled_ = true; public bool connectEnabled_pro { get { return connectEnabled_; } set { if (value == connectEnabled_) { return; } connectEnabled_ = value; NotifyPropertyChanged(() => connectEnabled_pro); } } #endregion #region backInfo NotifyPropertyChanged public void NotifyPropertyChanged<T>(Expression<Func<T>> property) { if (PropertyChanged == null) { return; } var memberExpression = property.Body as MemberExpression; if (memberExpression == null) { return; } PropertyChanged.Invoke(this, new PropertyChangedEventArgs(memberExpression.Member.Name)); } public event PropertyChangedEventHandler PropertyChanged; #endregion #region disconnectEnabled Property private bool disconnectEnabled_ = false; public bool disconnectEnabled_pro { get { return disconnectEnabled_; } set { if (value == disconnectEnabled_) { return; } disconnectEnabled_ = value; NotifyPropertyChanged(() => disconnectEnabled_pro); } } #endregion #region sendEnabled Property private bool sendEnabled_ = false; public bool sendEnabled_pro { get { return sendEnabled_; } set { if (value == sendEnabled_) { return; } sendEnabled_ = value; NotifyPropertyChanged(() => sendEnabled_pro); } } #endregion } private void FormMain_Load(object sender, EventArgs e) { initializeUI(); binding(); } private void binding()//Binding property with helper_ and automatically update data. { textBoxInfo.DataBindings.Add("Text", helper_, "backInfo_pro"); buttonConnect.DataBindings.Add("Enabled", helper_, "connectEnabled_pro"); buttonDisconnect.DataBindings.Add("Enabled", helper_, "disconnectEnabled_pro"); buttonSend.DataBindings.Add("Enabled", helper_, "sendEnabled_pro"); } private void initializeUI() { comboBoxSendEncoding.SelectedIndex = 2; comboBoxReceiveEncoding.SelectedIndex = 2; } private void buttonDisconnect_Click(object sender, EventArgs e) { try { if (socket_ == null) { return; } socket_.Close(); if (socket_ == null) { this.showBackInfo(Tip.disconnectFail); } else { helper_.connectEnabled_pro = true; helper_.disconnectEnabled_pro = false; helper_.sendEnabled_pro = false; this.showBackInfo(Tip.disconnectOK); } } catch (System.Exception ex) { this.showBackInfo(ex.Message); } } private void buttonSend_Click(object sender, EventArgs e) { try { string sendStr = textBoxSendData.Text; if (string.IsNullOrEmpty(sendStr)) { showBackInfo(Tip.sendDataEmpty); return; } if (!socket_.Connected) { showBackInfo(Tip.notConnect); return; } showBackInfo(Tip.sending); string sendEncodingName = comboBoxSendEncoding.Text; if (string.IsNullOrEmpty(sendEncodingName)) { showBackInfo(Tip.sendEncodingEmpty); return; } string receiveEncodingName = comboBoxReceiveEncoding.Text; if (string.IsNullOrEmpty(receiveEncodingName)) { showBackInfo(Tip.receiveEncodingEmpty); return; } Encoding sendEncoding = Encoding.GetEncoding(sendEncodingName); receiveEncoding_ = Encoding.GetEncoding(receiveEncodingName); sendStr += checkBoxAutoAddLineBreak.Checked ? lineBreak_ : "";//Automaticall add line break.SMTP/POP3/IMAP need. byte[] sendData = null; if (checkBoxToBase64.Checked) { sendData = Base64Sp.tobase64Bytes(sendStr, sendEncoding); } else { sendData = sendEncoding.GetBytes(sendStr); } socket_.Send(sendData); showBackInfo(Tip.sendCompleted + Tip.receiving); if (checkBoxAutoClear.Checked) { textBoxSendData.Text = ""; } } catch (System.Exception ex) { showBackInfo(ex.Message); } } private void receiveCallBack() { int receiveTimes_max = 5; int receiveTimes_accmulate = 0; while (true) { try { if (socket_ == null) { break; } byte[] receiveBuffer_ = new byte[receiveLen_max_]; int receiveLen = socket_.Receive(receiveBuffer_); #region Automatically disconnect when receive empty times reach receiveTimes_max if (receiveLen <= 0) { if (receiveTimes_accmulate > receiveTimes_max) { showBackInfo(Tip.lostConnect, true); this.Invoke((Action)(() => { buttonDisconnect_Click(null, EventArgs.Empty); })); break; } Thread.Sleep(1000); receiveTimes_accmulate++; continue; } #endregion receiveTimes_accmulate = 0;//If received data,times reset 0. string receiveStr = receiveEncoding_.GetString(receiveBuffer_, 0, receiveLen); if (needConvertBase64Received_) { receiveStr = Base64Sp.toNormalStr(receiveStr, receiveEncoding_); } showBackInfo(receiveStr, true); } catch (System.Exception ex) { break; } } } private class Tip { public static string base64ToNormalTip = "Convert base64 string that selected in the info to normal string with encode.Then auto copy result to clipboard."; public static string connectOK = "Connect OK!"; public static string connectFail = "Connect Fail!"; public static string disconnectOK = "Disconnect OK!"; public static string disconnectFail = "Disconnect Fail!"; public static string hostEmpty = "Host is empty!"; public static string notConnect = "Not connect!"; public static string portEmpty = "Port is empty!"; public static string portIllegal = "Port is illegal!"; public static string receiveEncodingEmpty = "Receive encode is empty!"; public static string receiveEncodingTip = "Different protocol need different encoding!"; public static string receiving = "Receiving..."; public static string receiveCompleted = "Receive completed!"; public static string sendDataEmpty = "Send data is empty!"; public static string sendEncodingEmpty = "Send encode is empty!"; public static string sendEncodingTip = "Different protocol need different encoding!"; public static string sending = "Sending..."; public static string sendCompleted = "Send data completed!"; public static string sendDataTip = "You may need to add line break when communicate by SMTP/IMAP/POP3 etc.!"; public static string toBase64Tip = "You may need convert string to base64 when send user name on SMTP."; } private void buttonBase64StrToNormalStr_Click(object sender, EventArgs e) {//Need convert to normal string when received base64 string. try { string base64Str = ""; base64Str = textBoxInfo.SelectedText; if (string.IsNullOrEmpty(base64Str)) { return; } string receiveEncodingName = comboBoxReceiveEncoding.Text; if (string.IsNullOrEmpty(receiveEncodingName)) { showBackInfo(Tip.receiveEncodingEmpty); return; } receiveEncoding_ = Encoding.GetEncoding(receiveEncodingName); string normalStr = Base64Sp.toNormalStr(base64Str, receiveEncoding_); Clipboard.SetText(normalStr); MessageBox.Show(normalStr); } catch (System.Exception ex) { MessageBox.Show(ex.Message); } } private void textBoxSendData_MouseHover(object sender, EventArgs e) { toolTipInfo.Show(Tip.sendDataTip, sender as Control); } private void checkBoxToBase64_MouseHover(object sender, EventArgs e) { toolTipInfo.Show(Tip.toBase64Tip, sender as Control); } private void comboBoxSendEncoding_MouseHover(object sender, EventArgs e) { toolTipInfo.Show(Tip.sendEncodingTip, sender as Control); } private void comboBoxReceiveEncoding_MouseHover(object sender, EventArgs e) { toolTipInfo.Show(Tip.receiveEncodingTip, sender as Control); } private void buttonBase64StrToNormalStr_MouseHover(object sender, EventArgs e) { toolTipInfo.Show(Tip.base64ToNormalTip, sender as Control); } } }

転載は出典を明記してくださいhttp://blog.csdn.net/xxdddail/article/details/9471079