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マルチスレッドクライアント.