由于某种原因,我的套接字显示了在代码的另一部分中收到的数据。 例如,当我登录它工作正常但我从服务器发送聊天消息,它显示从登录发送的用户名。
以下是服务器的网络类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using System.IO;
namespace Banshee_Server
{
class Network
{
public Socket listener;
IPEndPoint localEndPoint;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public static Dictionary<Socket, Player> dictionary = new Dictionary<Socket, Player>();
public Player getPlayer(Socket socket)
{
if (socket != null)
{
if(dictionary.ContainsKey(socket))
{
return dictionary[socket];
}
else
{
return null;
}
}
else
{
return null;
}
}
public bool playerIsLoggedIn(String player)
{
try
{
foreach (Socket sock in dictionary.Keys)
{
if (getPlayer(sock).Name.ToLower() == player.ToLower())
{
return true;
}
}
return false;
}
catch {
return true;
}
}
public static int getFreePlayerIndex
{
get { return Network.dictionary.Count(); }
}
netHandler handlers = new netHandler();
public Network(Socket socket, int port)
{
this.listener = socket;
localEndPoint = new IPEndPoint(IPAddress.Loopback, port);
}
public void bindListener()
{
listener.Bind(localEndPoint);
}
public void startListening()
{
try
{
listener.Listen(100);
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public void AcceptCallback(IAsyncResult ar){
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
startListening();
handler.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), handler);
Common common = new Common();
common.appendLog("New Connection received from " + handler.RemoteEndPoint.ToString());
}
public void ReadCallback(IAsyncResult ar){
Socket handler = (Socket)ar.AsyncState;
try
{
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
StringBuilder sb = new StringBuilder();
byte[] byteData = new byte[bytesRead];
byteData = buffer;
byte[] readData = new byte[byteData.Length - 1];
Buffer.BlockCopy(byteData, 1, readData, 0, readData.Length);
sb.Append(Encoding.ASCII.GetString(readData));
String data = sb.ToString();
handlers.handleData(handlers.getHandlerType(byteData[0]), data, handler);
handler.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), handler);
}
else
{
handler.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), handler);
}
}
catch
{
}
}
private static void sendFileCallback(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
client.EndSendFile(ar);
}
public void Send(Socket sock, String data, byte dataType)
{
byte[] byteType = new byte[1];
byteType[0] = dataType;
int bufferSize = byteType.Length + Encoding.ASCII.GetBytes(data).Length;
var ms = new MemoryStream(new byte[bufferSize], 0, bufferSize, true, true);
ms.Write(byteType, 0, byteType.Length);
ms.Write(Encoding.ASCII.GetBytes(data), 0, Encoding.ASCII.GetBytes(data).Length);
byte[] byteData = ms.GetBuffer();
sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
}
public void SendtoAll(String data, byte dataType)
{
try
{
foreach (Socket sock in dictionary.Keys)
{
try
{
Send(sock, data, dataType);
}
catch
{
handlers.logoutPlayer(sock, this);
}
}
}
catch { }
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
}
}
这是来自客户的网络类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace Ghoul_Engine
{
class network
{
public Socket sock;
public const int BufferSize = 1024;
public Byte[] buffer = new Byte[BufferSize];
public IPEndPoint RemoteEndPoint;
public network()
{
}
public void beginConnect(Socket socket)
{
sock = socket;
try
{
sock.BeginConnect(RemoteEndPoint, new AsyncCallback(onConnect), sock);
}
catch
{
MessageBox.Show("Could not connect to remote server. Perhaps it's down.");
}
}
public void onConnect(IAsyncResult ar)
{
try
{
sock.EndConnect(ar);
sock.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), sock);
} catch{
MessageBox.Show("Error connecting to server, it could be down!");
}
}
public void ReadCallback(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
try
{
int bytesRead = sock.EndReceive(ar);
if (bytesRead > 0)
{
StringBuilder sb = new StringBuilder();
byte[] byteData = new byte[bytesRead];
byteData = buffer;
byte[] readData = new byte[byteData.Length - 1];
Buffer.BlockCopy(byteData, 1, readData, 0, readData.Length);
sb.Append(Encoding.ASCII.GetString(readData));
String data = sb.ToString();
Program.netHandlers.handleData(Program.netHandlers.getHandlerType(byteData[0]), data, sock);
if(sock.Connected){
sock.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), sock);
}
}
else
{
if(sock.Connected){
sock.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), sock);
}
}
}
catch { }
}
public void Send(String data, byte dataType)
{
byte[] byteType = new byte[1];
byteType[0] = dataType;
int bufferSize = byteType.Length + Encoding.ASCII.GetBytes(data).Length;
var ms = new MemoryStream(new byte[bufferSize], 0, bufferSize, true, true);
ms.Write(byteType, 0, byteType.Length);
ms.Write(Encoding.ASCII.GetBytes(data), 0, Encoding.ASCII.GetBytes(data).Length);
byte[] byteData = ms.GetBuffer();
sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public void closeSocket()
{
try
{
if (sock.Connected)
{
sock.Close();
}
}
catch { }
}
public Socket getSocket()
{
return sock;
}
}
}
有什么想法吗?
答案 0 :(得分:2)
在您的服务器中,您拥有buffer
类的Network
成员,但每个客户端同时发生多个执行路径。如果您尝试为所有客户端使用相同的缓冲区,那么您将遇到这些冲突。
我建议您不要使用共享缓冲区,而是为每条消息使用单独的缓冲区。
答案 1 :(得分:0)
你的大部分代码在这里:
StringBuilder sb = new StringBuilder();
byte[] byteData = new byte[bytesRead];
byteData = buffer;
byte[] readData = new byte[byteData.Length - 1];
Buffer.BlockCopy(byteData, 1, readData, 0, readData.Length);
sb.Append(Encoding.ASCII.GetString(readData));
String data = sb.ToString();
可以简单地替换为:
String data = Encoding.ASCII.GetString(buffer, 0, bytesRead);
至于你的问题,我发布的代码中没有看到任何明显的内容。问题可能出在 handleData()方法中。