你好社区, 我遇到了一个大问题。 我想用C#创建一个客户端 - 服务器应用程序。
但是如果我将数据作为byte []发送给我的客户端,他会在服务器发送时获得更多字节。
如果我使用字符串x = Encoding.UTF8.GetString(bytesFromServer); 此字符串中的信息少于我的服务器上的信息。
我真的很困惑。 我希望你能帮助我。
服务器代码:
public class Server
{
private static object serverLock = new object();
private static int port = 5177;
private static Socket serverSocket;
private class ConnectionInfo
{
public string deviceName;
public Socket Socket;
public byte[] Buffer;
}
private static List<ConnectionInfo> connections = new List<ConnectionInfo>();
public static void Start()
{
try
{
createAndStartSocket();
for (int i = 0; i < 10; i++)
{
serverSocket.BeginAccept(new AsyncCallback(acceptCallback), serverSocket);
}
}
catch (Exception e)
{
Debug.WriteLine("Error: ");
Debug.WriteLine(e.ToString());
}
}
public static void Stop()
{
try
{
serverSocket.Close();
}
catch
{
Debug.WriteLine("Error while Closing Socket!");
}
}
private static void createAndStartSocket()
{
IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, port);
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Blocking = false;
serverSocket.Bind(myEndpoint);
serverSocket.Listen((int)SocketOptionName.MaxConnections); ;
}
private static void acceptCallback(IAsyncResult result)
{
ConnectionInfo connection = new ConnectionInfo();
try
{
Socket s = (Socket)result.AsyncState;
connection.Socket = s.EndAccept(result);
connection.Socket.Blocking = false;
connection.Buffer = new byte[1024];
lock (connections)
{
connections.Add(connection);
}
Debug.WriteLine("New connection from " + s);
// Start Receive
connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.Partial, new AsyncCallback(receiveCallback), connection);
serverSocket.BeginAccept(new AsyncCallback(acceptCallback), result.AsyncState);
}
catch (Exception e)
{
closeConnection(connection);
Debug.WriteLine("Exception: ");
Debug.WriteLine(e.ToString());
}
}
private static void closeConnection(ConnectionInfo connection)
{
connection.Socket.Close();
lock (connections)
{
connections.Remove(connection);
}
}
private static void receiveCallback(IAsyncResult result)
{
ConnectionInfo connection = (ConnectionInfo)result.AsyncState;
try
{
int bytesRead = connection.Socket.EndReceive(result);
if (0 != bytesRead)
{
string command = String.Empty;
command = UTF8Encoding.UTF8.GetString(connection.Buffer);
byte[] answer = DataController.GetData(command);
lock (connections)
{
foreach (ConnectionInfo conn in connections)
{
if (connection == conn)
{
conn.Socket.Send(answer, answer.Length,
SocketFlags.Partial);
}
}
}
connection.Socket.BeginReceive(connection.Buffer, 0,
connection.Buffer.Length, SocketFlags.Partial,
new AsyncCallback(receiveCallback), connection);
}
}
catch
{
closeConnection(connection);
}
}
}
和客户:
public class SocketInfo
{
public byte[] Buffer = new byte[1024];
public Socket Socket = null;
public List<byte> byteList = new List<byte>();
}
public class Connection
{
private string _address;
private int _port;
private IPEndPoint _clientEndpoint;
private List<SocketInfo> socketList = new List<SocketInfo>();
public bool Start(string address, int port)
{
_address = address;
_port = port;
IPAddress add = IPAddress.Parse(_address);
_clientEndpoint = new IPEndPoint(add, _port);
_address = _clientEndpoint.Serialize().ToString();
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SocketInfo info = new SocketInfo();
info.Socket = clientSocket;
lock (socketList)
{
socketList.Add(info);
}
Debug.Write("Connecting... ");
try
{
info.Socket.Connect(_clientEndpoint);
Debug.WriteLine("Done.");
info.Socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), info);
return true;
}
catch (Exception e)
{
lock (socketList)
{
socketList.Remove(info);
}
Debug.WriteLine("Fail.");
Debug.WriteLine(e);
return false;
}
}
public bool SendRequestToServer(string[] command)
{
try
{
switch (command[0])
{
case "service":
Thread th = new Thread(new ThreadStart(ServicesThread));
th.Start();
break;
default:
break;
}
return true;
}
catch
{
return false;
}
}
private void ServicesThread()
{
try
{
byte[] request = Encoding.UTF8.GetBytes("runningservices");
lock (socketList)
{
foreach (SocketInfo si in socketList)
{
si.Socket.Send(request, request.Length,
SocketFlags.None);
Debug.WriteLine("serviceRequest sendet!");
si.Socket.BeginReceive(si.Buffer, 0,
si.Buffer.Length, SocketFlags.None,
new AsyncCallback(receiveCallback), si);
}
}
}
catch (Exception e)
{
Console.WriteLine("Unable to send data. Connection lost.");
}
Thread.Sleep(10);
Debug.WriteLine("Services thread stopped.");
}
private void receiveCallback(IAsyncResult result)
{
SocketInfo info = (SocketInfo)result.AsyncState;
try
{
int bytesToRead = info.Socket.EndReceive(result);
if (bytesToRead > 0)
{
info.byteList.AddRange(info.Buffer);
// Get the rest of the data.
if (bytesToRead == info.Buffer.Length)
{
info.Socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, 0,
new AsyncCallback(receiveCallback), info);
}
else
{
if (info.byteList.Count > 0)
{
byte[] completeMessage = info.byteList.ToArray();
string incommingResult = Encoding.UTF8.GetString(completeMessage);
info.byteList.Clear();
//Following Code
info.Socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, 0,
new AsyncCallback(receiveCallback), info);
}
}
}
else
{
if (info.byteList.Count > 0)
{
byte[] completeMessage = info.byteList.ToArray();
string incommingResult = Encoding.UTF8.GetString(completeMessage);
info.byteList.Clear();
//Following Code
}
}
}
catch (Exception e)
{
lock (socketList)
{
socketList.Remove(info);
}
Debug.WriteLine("Client Disconnected.");
Debug.WriteLine(e);
}
}
}
在我的情况下,服务器说“answer.Length”= 9895 客户说“completeMessage.Length”= 9945。
我希望你能帮助我。 谢谢!
答案 0 :(得分:0)
您总是在这里添加缓冲区的全部内容:
info.byteList.AddRange(info.Buffer);
只需添加使用的缓冲区部分:
info.byteList.AddRange(info.Buffer.Take(bytesToRead));