我正在尝试用C#在Winforms中创建一个异步TCP服务器/客户端。我已经从控制台上做了,一切都很好。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void StartListener_Click(object sender, EventArgs e)
{
AsyncSocketListener.StartListener();
}
public class ObjectState {
public Socket socket = null;
public const int bufferSize = 1024;
public byte[] buffer = new byte[bufferSize];
public StringBuilder sb = new StringBuilder();
}
public class AsyncSocketListener {
public static ManualResetEvent completed = new ManualResetEvent(false);
public static void StartListener()
{
Form1 objects = new Form1();
byte[] bytes = new byte[1024];
int port = int.Parse(objects.ServerPort.Text);
IPAddress ip = IPAddress.Parse(objects.ServerIP.Text);
IPEndPoint ep = new IPEndPoint(ip, port);
Socket listener = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(ep);
listener.Listen(999999999);
while (true) {
completed.Reset();
MessageBox.Show("Listener started: Waiting for incoming connections", "Listener started", MessageBoxButtons.OK, MessageBoxIcon.Information);
listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
}
}
catch (Exception a) {
MessageBox.Show(a.Message, "Error - Listener failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private static void AcceptCallBack(IAsyncResult ar) {
completed.Set();
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);
ObjectState state = new ObjectState();
state.socket = handler;
handler.BeginReceive(state.buffer, 0, ObjectState.bufferSize, 0, new AsyncCallback(ReadCallBack), state);
}
private static void ReadCallBack(IAsyncResult ar)
{
string content = String.Empty;
ObjectState state = (ObjectState) ar.AsyncState;
Socket handler = state.socket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
content = state.sb.ToString();
if (content.IndexOf("<EOF>", StringComparison.Ordinal) > -1)
{
MessageBox.Show($"Read: {content.Length} bytes from socket Data: {content}", "Socket data", MessageBoxButtons.OK, MessageBoxIcon.Information);
Send(handler, content);
}
else
{
handler.BeginReceive(state.buffer, 0, ObjectState.bufferSize, 0, new AsyncCallback(ReadCallBack), state);
}
}
}
private static void Send(Socket handler, String content)
{
byte[] byteData = Encoding.ASCII.GetBytes(content);
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try {
Socket handler = (Socket) ar.AsyncState;
int byteSent = handler.EndSend(ar);
MessageBox.Show($"Sent: {byteSent} to client", "Socket data", MessageBoxButtons.OK, MessageBoxIcon.Information);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e) {
MessageBox.Show(e.Message, "Socket Callback Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}
当使用GUI时,我的服务器有问题。在我的AsyncSocketListener
类中,StartListener
函数无法捕获GUI文本框中传递的值。
Form1 objects = new Form1();
byte[] bytes = new byte[1024];
int port = int.Parse(objects.ServerPort.Text);
IPAddress ip = IPAddress.Parse(objects.ServerIP.Text);
IPEndPoint ep = new IPEndPoint(ip, port);
你知道这是怎么回事吗?为什么我不能从类中获取值?
我是C#新手,如果这是一个愚蠢的问题,我很抱歉。
1条答案
按热度按时间w6lpcovy1#
如果你在监听器代码中看这一行
您正在创建Form的一个全新示例,然后尝试使用此处的值。
相反,您需要将引用传递给原始Form。试试这个
然后像这样传递引用;
您还可以做一些其他的事情来改进代码(参见注解),包括将“
objects
“重命名为更有意义的名称,例如“form
“。实际上,将
Form1
与xml 2类完全解耦会更好,只需将值传递给侦听器,如下所示:像这样传递引用;