C# 当通过套接字接收信息时,应用程序停止
我正在为学校开发C客户机服务器应用程序,我有一个小问题。当我在应用程序中使用管理员登录时,一切正常,信息通过套接字传递,但当我需要通过套接字获取客户端列表时,管理员表单上会显示“无响应”,其他情况不会发生 有人能告诉我为什么在登录时可以工作,然后就不再工作了吗?谢谢 以下是我的项目的一些部分: 登录部分工作正常:C# 当通过套接字接收信息时,应用程序停止,c#,sockets,client-server,C#,Sockets,Client Server,我正在为学校开发C客户机服务器应用程序,我有一个小问题。当我在应用程序中使用管理员登录时,一切正常,信息通过套接字传递,但当我需要通过套接字获取客户端列表时,管理员表单上会显示“无响应”,其他情况不会发生 有人能告诉我为什么在登录时可以工作,然后就不再工作了吗?谢谢 以下是我的项目的一些部分: 登录部分工作正常: private void btnLogin_Click(object sender, EventArgs e) { String user =
private void btnLogin_Click(object sender, EventArgs e)
{
String user = txtUser.Text;
String pass = txtPass.Text;
ClientConnectionHandler handler = ClientConnectionHandler.getInstance();
handler.sendMessage("#login#" + user + " " + pass + "#");
User u = (User) handler.receive();
if (u == null)
{
MessageBox.Show("Username/Password is wrong");
}
else
{
if (u.getRang().Equals("admin"))
{
(new AdminWin(u)).Show();
this.Hide();
}
else{
(new ClientWin(u)).Show();
this.Hide();
}
}
handler.kill();
}
getClientList部分,它不工作:
public partial class AdminWin : Form
{
private User user;
public AdminWin(User u)
{
user = u;
InitializeComponent();
ClientConnectionHandler handler = ClientConnectionHandler.getInstance();
handler.sendMessage("#getClientList# #");
handler.receive();
//listUsers.DataSource = users;
}
}
ClientConnectionHandler:
public class ClientConnectionHandler
{
private static ClientConnectionHandler INSTANCE;
private static Socket socket;
private ClientConnectionHandler()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234);
socket.Connect("127.0.0.1", 1234);
}
public static ClientConnectionHandler getInstance()
{
if (INSTANCE == null)
INSTANCE = new ClientConnectionHandler();
return INSTANCE;
}
public void sendMessage(String message)
{
byte[] buffer = new byte[1024];
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(buffer);
formatter.Serialize(stream, message);
stream.Flush();
socket.Send(buffer, buffer.Length, 0);
}
public Object receive()
{
byte[] buffer = new byte[10240];
socket.Receive(buffer);
return toObject(buffer);
}
private Object toObject(byte[] byteArray)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(byteArray, 0, byteArray.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
public void kill()
{
socket.Close();
}
}
class ServerConnectionHandler
{
private Socket socket;
public ServerConnectionHandler(Socket socket)
{
this.socket = socket;
}
public void handle()
{
byte[] data = new byte[1024];
int receivedDataLength = socket.Receive(data);
String stringData = new ASCIIEncoding().GetString(data);
stringData = stringData.Substring(stringData.IndexOf("#"));
Console.WriteLine(stringData);
string[] bySharp = stringData.Split('#');
string action = bySharp[1];
string info = bySharp[2];
Console.WriteLine(action + " " + info);
switch (action)
{
case "login": handleLogin(info); break;
case "getClientList": handleClientList(); break;
case "getCDsForClient": handleCDList(info); break;
case "addCDForClient": handleAdd(info); break;
case "remCD": handleRem(info); break;
case "modCD": handleMod(info); break;
}
}
private void handleLogin(string info)
{
string[] bySpace = info.Split(' ');
string user = bySpace[0];
string pass = bySpace[1];
User u = RepositoryManager.getInstance().getUser(user, pass);
sendToClient(toByteArray(u));
}
private void handleClientList()
{
sendToClient(toByteArray(RepositoryManager.getInstance().getClientList()));
}
private void handleCDList(string info)
{
long userId = long.Parse(info);
sendToClient(toByteArray(RepositoryManager.getInstance().getCDs(userId)));
}
private void handleAdd(string info)
{
string[] byTilda = info.Split('~');
long userId = long.Parse(byTilda[0]);
String cdName = byTilda[1];
String cdType = byTilda[2];
RepositoryManager.getInstance().addCD(userId, cdName,
cdType);
}
private void handleRem(string info)
{
string[] bySpace = info.Split(' ');
long userId = long.Parse(bySpace[0]);
long cdId = long.Parse(bySpace[1]);
RepositoryManager.getInstance().remCD(userId, cdId);
}
private void handleMod(string info)
{
string[] byTilda = info.Split('~');
long userId = long.Parse(byTilda[0]);
long cdId = long.Parse(byTilda[1]);
String newName = byTilda[2];
String newType = byTilda[3];
RepositoryManager.getInstance().modCD(userId, cdId,
newName, newType);
}
private void sendToClient(byte[] info)
{
socket.Send(info, info.Length, 0);
}
private byte[] toByteArray(Object o)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, o);
return ms.ToArray();
}
}
服务器类:
class Server
{
public static void Main()
{
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1234);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
socket.Bind(ipEndPoint);
socket.Listen(100);
Console.WriteLine("Server Started");
while (true)
{
Socket clientSocket = socket.Accept();
clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
Thread clientThread = new Thread(new ThreadStart(new ServerConnectionHandler(clientSocket).handle));
clientThread.Start();
}
}
}
以及ServerConnectionHandler:
public class ClientConnectionHandler
{
private static ClientConnectionHandler INSTANCE;
private static Socket socket;
private ClientConnectionHandler()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234);
socket.Connect("127.0.0.1", 1234);
}
public static ClientConnectionHandler getInstance()
{
if (INSTANCE == null)
INSTANCE = new ClientConnectionHandler();
return INSTANCE;
}
public void sendMessage(String message)
{
byte[] buffer = new byte[1024];
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(buffer);
formatter.Serialize(stream, message);
stream.Flush();
socket.Send(buffer, buffer.Length, 0);
}
public Object receive()
{
byte[] buffer = new byte[10240];
socket.Receive(buffer);
return toObject(buffer);
}
private Object toObject(byte[] byteArray)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(byteArray, 0, byteArray.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
public void kill()
{
socket.Close();
}
}
class ServerConnectionHandler
{
private Socket socket;
public ServerConnectionHandler(Socket socket)
{
this.socket = socket;
}
public void handle()
{
byte[] data = new byte[1024];
int receivedDataLength = socket.Receive(data);
String stringData = new ASCIIEncoding().GetString(data);
stringData = stringData.Substring(stringData.IndexOf("#"));
Console.WriteLine(stringData);
string[] bySharp = stringData.Split('#');
string action = bySharp[1];
string info = bySharp[2];
Console.WriteLine(action + " " + info);
switch (action)
{
case "login": handleLogin(info); break;
case "getClientList": handleClientList(); break;
case "getCDsForClient": handleCDList(info); break;
case "addCDForClient": handleAdd(info); break;
case "remCD": handleRem(info); break;
case "modCD": handleMod(info); break;
}
}
private void handleLogin(string info)
{
string[] bySpace = info.Split(' ');
string user = bySpace[0];
string pass = bySpace[1];
User u = RepositoryManager.getInstance().getUser(user, pass);
sendToClient(toByteArray(u));
}
private void handleClientList()
{
sendToClient(toByteArray(RepositoryManager.getInstance().getClientList()));
}
private void handleCDList(string info)
{
long userId = long.Parse(info);
sendToClient(toByteArray(RepositoryManager.getInstance().getCDs(userId)));
}
private void handleAdd(string info)
{
string[] byTilda = info.Split('~');
long userId = long.Parse(byTilda[0]);
String cdName = byTilda[1];
String cdType = byTilda[2];
RepositoryManager.getInstance().addCD(userId, cdName,
cdType);
}
private void handleRem(string info)
{
string[] bySpace = info.Split(' ');
long userId = long.Parse(bySpace[0]);
long cdId = long.Parse(bySpace[1]);
RepositoryManager.getInstance().remCD(userId, cdId);
}
private void handleMod(string info)
{
string[] byTilda = info.Split('~');
long userId = long.Parse(byTilda[0]);
long cdId = long.Parse(byTilda[1]);
String newName = byTilda[2];
String newType = byTilda[3];
RepositoryManager.getInstance().modCD(userId, cdId,
newName, newType);
}
private void sendToClient(byte[] info)
{
socket.Send(info, info.Length, 0);
}
private byte[] toByteArray(Object o)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, o);
return ms.ToArray();
}
}
您的读取方法有缺陷,无法按预期工作 TCP是基于流的,而不是基于消息的。“读取时”可以包含以下任何消息: 信息中微不足道的一部分 半封信 确切地说是一条信息 一个半消息 两条信息 因此,您需要使用某种方法来查看是否已收到完整的消息。最常用的方法是: 添加一个页脚,例如一个空行,表示消息结束 添加包含消息长度的固定长度标头 您还应该接受现有的.NET命名准则,并停止使用camelCase作为方法名称。你编写的不是Java