Я разрабатываю (или, во всяком случае, пытаюсь) программу, которая использует асинхронный сокет, предположительно, для передачи строк на сервер и клиент в любое время.
Эта программа требует, чтобы к серверу было подключено не более одного клиента. Я попробовал программирование сокетов, но обнаружил, что оно блокирует программу до тех пор, пока одна из них не получит что-то.
Поскольку у меня есть только базовое понимание программирования асинхронных сокетов, я выбрал самый простой, который смог найти, или, по крайней мере, самый простой, который смог понять.
Вот мой код для сервера:
public Socket g_server_conn;
public byte[] g_bmsg;
public bool check = false;
private void net_As_Accept(IAsyncResult iar)
{
Socket server_conn = (Socket)iar.AsyncState;
g_server_conn = server_conn.EndAccept(iar);
g_bmsg = new byte[1024];
check = true;
g_server_conn.BeginReceive(g_bmsg, 0, g_bmsg.Length, SocketFlags.None, new AsyncCallback(net_As_Receive), g_server_conn);
}
private void net_As_Send(IAsyncResult iar)
{
Socket server_conn = (Socket)iar.AsyncState;
server_conn.EndSend(iar);
}
private void net_As_Receive(IAsyncResult iar)
{
try
{
Socket server_conn = (Socket)iar.AsyncState;
server_conn.EndReceive(iar);
if (g_bmsg.Length != 0)
{
net_Data_Receive(Encoding.ASCII.GetString(g_bmsg, 0, g_bmsg.Length));
check = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "GG");
}
}
public void net_Data_Send(string msg2snd) // Function for sending through socket
{
MessageBox.Show(msg2snd);
byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg2snd);
g_server_conn.BeginSend(byData, 0, byData.Length, SocketFlags.None, new AsyncCallback(net_As_Send), g_server_conn);
g_server_conn.BeginReceive(g_bmsg, 0, g_bmsg.Length, SocketFlags.None, new AsyncCallback(net_As_Receive), g_server_conn);
}
private void net_Data_Receive(string txt)
{
if (lblBuffer.InvokeRequired)
lblBuffer.Invoke(new MethodInvoker(delegate { net_Data_Receive(txt); }));
else
lblBuffer.Text = txt;
if (txt.StartsWith("&"))
{
// Do something
}
}
И вот мой код для клиента:
private void net_As_Connect(IAsyncResult iar)
{
try
{
Socket client_conn = (Socket)iar.AsyncState;
client_conn.EndConnect(iar);
g_bmsg = new byte[1024];
check = true;
string toSendData = "&" + net_Name;
net_Data_Send(toSendData);
g_client_conn.BeginReceive(g_bmsg, 0, g_bmsg.Length, SocketFlags.None, new AsyncCallback(net_As_Receive), g_client_conn);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "GG");
}
}
private void net_As_Send(IAsyncResult iar)
{
Socket client_conn = (Socket)iar.AsyncState;
client_conn.EndSend(iar);
}
private void net_As_Receive(IAsyncResult iar)
{
if (g_bmsg.Length != 0)
{
net_Data_Receive(Encoding.ASCII.GetString(g_bmsg, 0, g_bmsg.Length));
check = false;
}
}
public void net_Data_Send(string msg2snd)
{
byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg2snd);
g_client_conn.BeginSend(byData, 0, byData.Length, SocketFlags.None, new AsyncCallback(net_As_Send), g_client_conn);
g_client_conn.BeginReceive(g_bmsg, 0, g_bmsg.Length, SocketFlags.None, new AsyncCallback(net_As_Receive), g_client_conn);
}
private void net_Data_Receive(string txt)
{
if (lblBuffer.InvokeRequired)
lblBuffer.Invoke(new MethodInvoker(delegate { net_Data_Receive(txt); }));
else
lblBuffer.Text = txt;
if (txt.StartsWith("&"))
{
// Do Something
}
else if (txt.StartsWith("$"))
{
// Do something Else
}
}
Теперь клиент может нормально подключиться к серверу. Клиент может даже отправить строку, содержащую имя пользователя, на Сервер, которая затем будет отображаться на Сервере. Затем Сервер отправляет имя своего пользователя Клиенту, которое клиент получает и отображает. Все, что отправляется, сохраняется в метке (lblBuffer).
Но потом, скажем, у меня есть следующий код:
private void btnSendData_Click(object sender, EventArgs e)
{
string posMov = "Stuff to send";
net_Data_Send(posMov);
}
Клиент ничего не получает. Помещение окна сообщения в функцию net_Data_Send(msg2snd) показывает, что сервер действительно отправляет сообщение. На самом деле, добавление окна сообщения в эту функцию заставляет ее работать (клиент ее получает) по причинам, которые я не знаю. Поскольку я не пытался отправить сообщение от клиента на сервер (кроме имени при подключении клиента), я предполагаю, что у клиента будет такая же проблема с отправкой на сервер.
Кроме того, когда он отправляет второе сообщение (поместив окно сообщения в функцию net_Data_Send), перезаписываются только части метки (lblBuffer). Итак, если меня зовут «Анон Э. Муз», и сервер отправляет это, когда клиент подключается, и я пытаюсь отправить, скажем, «0,0» (через нажатие кнопки), метка на клиенте будет читать «0,0 п Э. Мус».
Что я сделал не так? Могу ли я помочь в этом, пожалуйста?
Возможно, у меня проблема с net_Data_Receive и net_Data_Send?