我目前正在开发一个聊天程序。它包含一个表单(MainWindow)和一个类(TCPServerConnector)。MainWindow 是包含两个文本框、两个按钮和一个列表框的 UI。
在第一个文本框中,您必须编写要连接的服务器 ip,而不是单击“连接”按钮。第二个文本框包含您的书面文本,第二个按钮发送此文本。列表框应该显示程序从服务器接收到的所有聊天/文本,但我没有让它工作。
Main-Form 初始化 TCPServerConnector 的对象并将 IP 和文本传递给它。但是,当您收到一些文本时,班级必须将收到的文本传递给表单。
我尝试使用委托(以前从未使用过它们),但这并没有解决我的问题,我只是遇到了一些关于跨线程的异常..
还要创建 MainWindow 的新实例,因为它不引用 Main-Form 的旧实例。
我已经添加了下面类的代码,希望有人可以解决我的问题;)
主要形式:
public partial class MainWindow : Form
{
public MainWindow()
{
InitializeComponent();
}
TCPServerConnector TestConnection = new TCPServerConnector();
private void Form1_Load(object sender, EventArgs e)
{
}
private void srvConnect_Click(object sender, EventArgs e)
{
TestConnection.ConnectToServer(srvConnectionIP.Text.ToString());
}
private void srvSend_Click(object sender, EventArgs e)
{
TestConnection.SendEnteredString(srvTextToSend.Text.ToString());
}
private void FormMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
TestConnection.CloseConnection();
}
}
在“OnRecievedData”方法中,我添加了一个消息框来显示接收到的文本,因为现在我无法将它添加到表单列表框中。
TCPServerConnector 类:
class TCPServerConnector
{
private Socket m_sock;
private byte[] m_byBuff = new byte[256];
public void ConnectToServer(string ServerAddress)
{
try
{
if (m_sock != null && m_sock.Connected)
{
m_sock.Shutdown(SocketShutdown.Both);
System.Threading.Thread.Sleep(10);
m_sock.Close();
}
m_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint epServer = new IPEndPoint(IPAddress.Parse(ServerAddress), 399);
m_sock.Blocking = false;
AsyncCallback onconnect = new AsyncCallback(OnConnect);
m_sock.BeginConnect(epServer, onconnect, m_sock);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void OnConnect(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
try
{
if (sock.Connected)
SetupRecieveCallback(sock);
else
MessageBox.Show("Unable to establish connection");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void OnRecievedData(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
try
{
int nBytesRec = sock.EndReceive(ar);
if (nBytesRec > 0)
{
string sRecieved = Encoding.ASCII.GetString(m_byBuff, 0, nBytesRec);
MessageBox.Show(sRecieved); //TO SHOW IF SOMETHING HAPPENED. HERE IS MY PROBLEM
SetupRecieveCallback(sock);
}
else
{
Console.WriteLine("Client {0}, disconnected", sock.RemoteEndPoint);
sock.Shutdown(SocketShutdown.Both);
sock.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void SetupRecieveCallback(Socket sock)
{
try
{
AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void SendEnteredString(string EnteredData)
{
if (m_sock == null || !m_sock.Connected)
{
MessageBox.Show("You have to be connected to send something.");
return;
}
try
{
Byte[] byteDateLine = Encoding.ASCII.GetBytes(EnteredData.ToCharArray());
m_sock.Send(byteDateLine, byteDateLine.Length, 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void CloseConnection()
{
if (m_sock != null && m_sock.Connected)
{
m_sock.Shutdown(SocketShutdown.Both);
m_sock.Close();
}
}
}