服务器/客户端套接字连接问题
本文关键字:连接 问题 套接字 客户端 服务器 | 更新日期: 2023-09-27 18:02:37
首先,我的项目应该做什么,如果它会工作:
- 用c++编写的客户端连接到c#编写的服务端
- 当连接成功时,客户端发送"0"给服务器请求一个随机的十六进制字符串
- 如果客户端收到十六进制,他将发送"1"到服务器
- 现在客户端使用接收到的十六进制字符串做一些事情,然后将其发送回服务器
- 如果客户端对十六进制字符串所做的是正确的(基本无系统),他返回"1",否则他返回"0"
注意:接收/发送在客户端/服务器端工作,我测试了它之前只是发送1到服务器和服务器返回0如果接收到的字符串是1
现在到我的编码:这是用c#编写的服务器部分:
private static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private static List<Socket> clientSockets = new List<Socket>();
private const int PORT = 11111;
private static byte[] buffer = new byte[100];
private void ReceiveCallback(IAsyncResult AR)
{
Socket current = (Socket)AR.AsyncState;
int received;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
Console.WriteLine("Client Disconnected! (Forced)");
current.Close();
clientSockets.Remove(current);
return;
}
//That's how my Example before worked:
/*byte[] recBuf = new byte[1];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
if(text != "" && text.StartsWith("0"))
{
Console.WriteLine("Recieved: " + text);
string send = "1";
Console.WriteLine("Sending: " + send);
Byte[] data = ASCIIEncoding.ASCII.GetBytes(send);
current.Send(data);
Console.WriteLine("Sended!");
current.Shutdown(SocketShutdown.Both);
current.Close();
clientSockets.Remove(current);
Console.WriteLine("Client Disconnected!");
return;
}
current.BeginReceive(buffer, 0, 1, SocketFlags.None, ReceiveCallback, current);*/
//worked like a charm!
//That's my new Solution, that doesn't work:
byte[] recBuf = new byte[100];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
while (text != "")
{
Console.WriteLine("Received Data: " + text);
if (text.StartsWith("0") && text.Length < 32)
{
Console.WriteLine("Client requests Random HexString...");
string rand = GetRandomHexNumber(32);
Byte[] data = ASCIIEncoding.ASCII.GetBytes(rand);
current.Send(data);
Console.WriteLine("Sended HexString! - " + rand);
}
if (text.StartsWith("1") && text.Length < 32)
{
Console.WriteLine("Client recieved the HexString!");
}
if (text.Length > 32 && !text.StartsWith("0") && !text.StartsWith("1"))
{
Console.WriteLine("Result recieved!");
//here will be some authing process but for simplicity just return "1"
byte[] data = ASCIIEncoding.ASCII.GetBytes("1");
current.Send(data);
current.Shutdown(SocketShutdown.Both);
current.Close();
clientSockets.Remove(current);
Console.WriteLine("Client Disconnected!");
return;
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
}
private void AcceptCallback(IAsyncResult AR)
{
Socket socket;
try
{
socket = serverSocket.EndAccept(AR);
}
catch (ObjectDisposedException)
{
return;
}
clientSockets.Add(socket);
socket.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, socket);
Console.WriteLine("Client Connected!");
serverSocket.BeginAccept(AcceptCallback, null);
}
private void setupServer()
{
serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
serverSocket.Listen(0);
Console.WriteLine("Server Started!");
Console.WriteLine("Listening for Clients...");
serverSocket.BeginAccept(AcceptCallback, null);
}
private void CloseAllSockets()
{
foreach (Socket socket in clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
serverSocket.Close();
}
setupServer ();在控制台启动时启动!c#部分是c++方面唯一的问题,一切都很好!我真的希望有人能帮助我现在,因为我没有收到任何类型的帮助还在这个论坛上,我真的需要这个工作,我敢肯定这里有很多程序员可以帮助我(也许这只是一个逻辑问题,所以每一个答案或评论都是赞赏的)谢谢你的时间:)
Replace
while (text != "")
{
// .....................
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
if (text != "")
{
// .....................
// Notice there's no BeginReceive() here!
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
作为callback
参数传递给BeginReceive()
的函数通常不应该在循环中调用BeginReceive()
"直到会话结束"。相反,它应该只调用BeginReceive()
一次来挂起另一个读取操作,如果需要进一步的数据(即:"session in not over").