C#Socketクライアントのテスト

46816 ワード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Socket.Test
{

    public partial class frmSocketClient : Form
    {

        System.Collections.Concurrent.ConcurrentQueue<string> logs = new System.Collections.Concurrent.ConcurrentQueue<string>();
        // The response from the remote device.  
        //private static String response = String.Empty;
        private List sockets = new List();

        public frmSocketClient()
        {
            InitializeComponent();
        }
        private int successcount = 0;
        delegate void DeAppend(string txt);
        delegate void DeEnable(bool enable);
        delegate void DeCount();

        private string ip;
        private int port, clientsperthread, threads;
        private string data;
        private int repeat;
        private int interval, intervalPerSend, count;
        private bool islog = false;
        
        private void AppendToTextBox(string txt)
        {
            if (txtLog.InvokeRequired)
            {
                DeAppend de = new DeAppend(AppendToTextBox);
                this.Invoke(de, new object[] { txt });
            }
            else
            {
                if (chkBoxLog.Checked)
                {
                    txtLog.AppendText(txt);
                    txtLog.AppendText("\r
"); } } } private void Append(string s) { if (!islog) return; Monitor.Enter(logs); logs.Enqueue(string.Concat(s, "\r
")); Monitor.Exit(logs); } private void AppendLogToTextBox() { while (true) { if (logs.Count > 0) { StringBuilder sb = new StringBuilder(); Monitor.Enter(logs); string s; while (logs.TryDequeue(out s)) { sb.Append(s); } Monitor.Exit(logs); AppendToTextBox(sb.ToString()); sb.Clear(); } System.Threading.Thread.Sleep(300); } } private void Count() { if (this.InvokeRequired) { DeCount de = new DeCount(Count); this.Invoke(de, new object[] { }); } else { successcount++; this.Text = string.Concat("Socket Client Test - [Success connected: ", successcount, "]"); } } private void Error(string txt) { if (txtLog.InvokeRequired) { DeAppend de = new DeAppend(Error); this.Invoke(de, new object[] { txt }); } else { Console.WriteLine(txt); txtLog.AppendText(txt); txtLog.AppendText("\r
"); } } private void Enable(bool enable) { if (txtLog.InvokeRequired) { DeEnable de = new DeEnable(Enable); this.Invoke(de, new object[] { enable }); } else { btnConnect.Text = enable? "Close" : "Connect"; txtData.Enabled = enable; cmbRepeat.Enabled = enable; btnSend.Enabled = enable; cmbInterval.Enabled = enable; cmbIntervalPerSend.Enabled = enable; chkBoxLog.Enabled = enable; cmbCount.Enabled = enable; txtIP.Enabled = !enable; txtPort.Enabled = !enable; cmbThreads.Enabled = !enable; cmbClients.Enabled = !enable; } } private void btnConnect_Click(object sender, EventArgs e) { if (btnConnect.Text == "Connect") { Connect(); } else { try { foreach(var item in sockets) { item.Close(); } sockets.Clear(); } catch (Exception ex) { Error(ex.ToString()); } Enable(false); } } private void Connect() { islog = chkBoxLog.Checked; successcount = 0; ip = txtIP.Text; if(!int.TryParse(txtPort.Text, out port) || port == 0) { MessageBox.Show("port Required"); txtPort.Focus(); return; } if (!int.TryParse(cmbThreads.Text, out threads)) { MessageBox.Show("invaild Threads"); cmbThreads.Focus(); return; } if (!int.TryParse(cmbClients.Text, out clientsperthread)) { MessageBox.Show("invaild Clients"); cmbThreads.Focus(); return; } if (clientsperthread <= 0) clientsperthread = 1; if (threads <= 0) threads = 1; if (ip == "") { MessageBox.Show("IP Required"); txtIP.Focus(); return; } try { for (int i = 0; i < threads; i++) { Thread th = new Thread(new ParameterizedThreadStart(Start)); th.Start(i); } } catch (Exception ex) { Error(ex.ToString()); } } private void Start(object o) { int t = (int)o; for (int i = 0; i < clientsperthread; i++) { GSocket socket = new GSocket(ip, port); socket.Name = string.Concat("S", t, "-", i.ToString().PadLeft(6, '0')); socket.Append = Append; socket.Error = Error; socket.Enable = Enable; socket.Count = Count; socket.Connect(); AddSocket(socket); } } private void AddSocket(GSocket s) { Monitor.Enter(sockets); sockets.Add(s); Monitor.Exit(sockets); } private void frmSocketClient_Load(object sender, EventArgs e) { Thread th = new Thread(new System.Threading.ThreadStart(AppendLogToTextBox)); th.IsBackground = true; th.Start(); } private void btnSend_Click(object sender, EventArgs e) { btnSend.Enabled = false; try { islog = chkBoxLog.Checked; data = txtData.Text; repeat = int.Parse(cmbRepeat.Text); intervalPerSend = int.Parse(cmbIntervalPerSend.Text); interval = int.Parse(cmbInterval.Text); count = int.Parse(cmbCount.Text); Thread th = new Thread(new ThreadStart(Send)); th.Start(); } catch (Exception ex) { Error(ex.ToString()); } btnSend.Enabled = true; } private void Send() { if (count == 0) count = 1; for (int j = 0; j < count; j++) { for (int i = 0; i < sockets.Count; i++) { sockets[i].data = data; sockets[i].interval = intervalPerSend; sockets[i].repeat = repeat; sockets[i].SendData(); Console.WriteLine("Send data"); } if(interval > 0) Thread.Sleep(interval); } } } public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 256; // Receive buffer. public byte[] buffer = new byte[BufferSize]; // Received data string. //public StringBuilder sb = new StringBuilder(); } public class GSocket { // ManualResetEvent instances signal completion. private static ManualResetEvent connectDone = new ManualResetEvent(false); private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent receiveDone = new ManualResetEvent(false); private Socket client = null; public string data { get; set; } public int repeat { get; set; } public int interval { get; set; } private int _port = 0; private string Ip = null; private bool isconnected = false; private Random rd = new Random(); private string GetRand() { return rd.Next(1, 100).ToString(); } public GSocket(string ip, int port) { Ip = ip; _port = port; } public string Name { get; set; } public Action<string> Append { get; set; } public Action<string> Error { get; set; } public Action<bool> Enable { get; set; } public Action Count { get; set; } public void Connect() { try { // Establish the remote endpoint for the socket. // The name of the // remote device is "host.contoso.com". //IPHostEntry ipHostInfo = Dns.GetHostEntry(txtIP.Text); //IPAddress ipAddress = ipHostInfo.AddressList[0]; IPAddress ipAddress = IPAddress.Parse(Ip); IPEndPoint remoteEP = new IPEndPoint(ipAddress, _port); // Create a TCP/IP socket. client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Connect to the remote endpoint. client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); connectDone.WaitOne(); Enable(true); //Append("Connected"); // Send test data to the remote device. //Send(client, "This is a test"); //Send(client, txtData.Text); //sendDone.WaitOne(); // Receive the response from the remote device. Receive(client); //receiveDone.WaitOne(); // Write the response to the console. //Append(string.Concat("Response received : ", response)); isconnected = true; Count(); } catch (Exception ex) { isconnected = false; Error(string.Concat("[", Name, "]", ex.ToString())); } } public void Close() { try { Send(client, "exit"); client.Shutdown(SocketShutdown.Both); //client.Close(); } catch (Exception ex) { Error(string.Concat("[", Name, "]", ex.ToString())); } } private void ConnectCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete the connection. client.EndConnect(ar); Append(string.Concat("[", Name, "]Socket connected")); // Signal that the connection has been made. connectDone.Set(); } catch (Exception ex) { Error(string.Concat("[", Name, "]", ex.ToString())); } } private void Receive(Socket client) { try { // Create the state object. StateObject state = new StateObject(); state.workSocket = client; //Append("Begin to receive"); // Begin receiving the data from the remote device. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception ex) { Error(string.Concat("[", Name, "]", ex.ToString())); } } private void ReceiveCallback(IAsyncResult ar) { try { //Append("Start to receive"); // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // Read data from the remote device. int bytesRead = client.EndReceive(ar); //Append("Received " + bytesRead); if (bytesRead > 0) { // There might be more data, so store the data received so far. Append(string.Concat("[", Name, "][", GetTime(), "]Received: ", Encoding.ASCII.GetString(state.buffer, 0, bytesRead))); // Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { // Signal that all bytes have been received. receiveDone.Set(); } } catch (Exception ex) { Error(string.Concat("[", Name, "]", ex.ToString())); } } private string GetTime() { return DateTime.Now.ToString("yy-MM-dd HH:mm:ss"); } private void Send(Socket client, String data) { try { string newdata = data.Replace("{rand}", GetRand()); // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(newdata); // Begin sending the data to the remote device. client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); } catch (Exception ex) { Error(string.Concat("[", Name, "]", ex.ToString())); } } private void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = client.EndSend(ar); //Append(string.Format("Sent {0} bytes to server.", bytesSent)); // Signal that all bytes have been sent. sendDone.Set(); } catch (Exception ex) { Error(string.Concat("[", Name, "]", ex.ToString())); } } public void SendData() { if (!isconnected) { return; } Append(string.Concat("[", Name, "][", GetTime(), "]Data sent[", repeat, " Times]")); if (repeat > 1) { for (int i = 0; i < repeat; i++) { Send(client, data); //sendDone.WaitOne(); if (interval > 1) { Thread.Sleep(interval); } } } else { Send(client, data); //sendDone.WaitOne(); } } } }

 
socketマルチスレッドクライアント.