Код ниже основан на серверный сокет пример и встроенный в winForms,
Это весь код (для его запуска вам понадобятся: textBoxes: tBoxTcpIpStatus
и tBoxSend
, кнопка button1
и backgroundWorker bgWorkerSocketListener
):
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;
namespace SocketServer_WinForms
{
public partial class Form1 : Form
{
public static ManualResetEvent allDone = new ManualResetEvent(false); //Thread signal
internal Socket handler;
internal Socket listener;
public Form1()
{
InitializeComponent();
bgWorkerSocketListener.DoWork += bgWorkerSocketListener_DoWork;
bgWorkerSocketListener.WorkerReportsProgress = true;
bgWorkerSocketListener.RunWorkerAsync();
}
public void bgWorkerSocketListener_DoWork(object sender, DoWorkEventArgs e)
{
//Establish the local endpoint for the socket, the DNS name of the computer
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
AppendTextBox("Host IP: " + Convert.ToString(ipAddress) + Environment.NewLine);
//Create a TCP/IP socket
listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
//Bind the socket to the local endpoint and listen for incoming connections
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
//Set the event to nonsignaled state
allDone.Reset();
//Start an asynchronous socket to listen for connections
AppendTextBox("Waiting for a connection...");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
//Wait until a connection is made before continuing
allDone.WaitOne();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
listener = (Socket)ar.AsyncState;
handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
try
{
//Retrieve the state object and the handler socket from the asynchronous state object
StateObject state = (StateObject)ar.AsyncState;
handler = state.workSocket;
//Read data from the client socket
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
//There might be more data, so store the data received so far
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
//Check for end-of-file tag. If it is not there, read more data
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
//All the data has been read from the client. Display it on the console
ClearTextBox();
AppendTextBox("Read " + content.Length + " bytes from client: " + content);
//Echo the data back to the client.
Send(handler, content);
}
else
{
//Not all data received, get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public void Send(Socket handler, String data)
{
if (handler == null)
tBoxSend.Text = "Client disconnected";
else
{
//Convert the string data to byte data using ASCII encoding
byte[] byteData = Encoding.ASCII.GetBytes(data);
//Begin sending the data to the remote device
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
}
public void SendCallback(IAsyncResult ar)
{
try
{
//Retrieve the socket from the state object
handler = (Socket)ar.AsyncState;
//Complete sending the data to the remote device
int bytesSent = handler.EndSend(ar);
AppendTextBox(Environment.NewLine + "Sent " + bytesSent + " bytes to client.");
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public void button1_Click(object sender, EventArgs e)
{
Send(handler, tBoxSend.Text + "<EOF>");
}
public void AppendTextBox(string value) //Appends text to Fail Tracker textbox, prevents UI from freezing
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
tBoxTcpIpStatus.Text += value;
}
public void ClearTextBox() //Appends text to Fail Tracker textbox, prevents UI from freezing
{
if (InvokeRequired)
{
this.Invoke(new Action(ClearTextBox));
return;
}
tBoxTcpIpStatus.Clear();
}
}
public class StateObject
{
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
// Client socket.
public Socket workSocket = null;
}
}
Клиент может успешно отправить данные, и сервер вернет их обратно.
Но почему моя кнопка не отправляет данные клиенту? Это доходит до SendCallback
метод, потому что я могу видеть tBoxTcpIpStatus
обновление, но клиент ничего не получает.
public void button1_Click(object sender, EventArgs e)
{
Send(handler, tBoxSend.Text + "<EOF>");
}
Вот мой клиентский код на всякий случай, он отлично работает:
using System;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Timers;
namespace SocketClient_WinForms
{
public partial class Form1 : Form
{
// The port number for the remote device.
private const int port = 11000;
// 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 System.Timers.Timer myTimer;
internal Socket client;
public Form1()
{
InitializeComponent();
}
private void StartClient()
{
System.Threading.Tasks.Task.Run //Begin a new thread
(() =>
{
CheckForIllegalCrossThreadCalls = false;
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");
IPAddress ipAddress = ipHostInfo.AddressList[0];
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();
// Send test data to the remote device.
Send(client, textBox2.Text.ToString() + comboBox1.Text);
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
});//thread
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
if (textBox1.Text == "")
AppendTextBox("Socket connected to " + client.RemoteEndPoint.ToString() + "tt" + Environment.NewLine);
else
AppendTextBox(Environment.NewLine + "Socket connected to " + client.RemoteEndPoint.ToString() + "tt" + Environment.NewLine);
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private void ReceiveCallback(IAsyncResult ar)
{
System.Threading.Tasks.Task.Run //Begin a new thread
(() =>
{
String content = String.Empty;
try
{
// Retrieve the state object and the client socket from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
//Check for end-of-file tag. If it is not there, read more data
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
//All the data has been read from the client. Display it on the console
AppendTextBox("Read " + content.Length + " bytes from server: " + content);
}
else
{
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
/*response*/
content = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
});//thread
}
private void Send(Socket client, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
}
private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
AppendTextBox("Sent " + bytesSent + " bytes to server." + "tt" + Environment.NewLine);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public void AppendTextBox(string value) //prevents UI from freezing
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
textBox1.Text += value;
//move the caret to the end of the text
textBox1.SelectionStart = textBox1.TextLength;
textBox1.ScrollToCaret();
}
private void button2_Click(object sender, EventArgs e)
{
// Send test data to the remote device.
StartClient();
}
}
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();
}
}
Любая помощь будет принята с благодарностью, спасибо.