通过tcp/ip处理的c#网络流
我希望有人能告诉我为什么在我的tcpListener/tcpClient代码中出现对象处理异常 在acceptConnections和connectToServer方法中,我使用keepalive方法来告诉我何时断开连接,并且工作正常 但是,如果我取消对sendMsg方法的for循环的注释,我将在服务器上得到一个ObjectDisposedException,在客户端得到一个IOException SendMsg中tcpClient.getStream()的NetworkStream似乎是问题所在,但我不确定为什么它会得到一个已处理的流。我需要2个线程来处理它吗通过tcp/ip处理的c#网络流,c#,tcp,tcplistener,networkstream,objectdisposedexception,C#,Tcp,Tcplistener,Networkstream,Objectdisposedexception,我希望有人能告诉我为什么在我的tcpListener/tcpClient代码中出现对象处理异常 在acceptConnections和connectToServer方法中,我使用keepalive方法来告诉我何时断开连接,并且工作正常 但是,如果我取消对sendMsg方法的for循环的注释,我将在服务器上得到一个ObjectDisposedException,在客户端得到一个IOException SendMsg中tcpClient.getStream()的NetworkStream似乎是问题所
static void Main(string[] args)
{
server.Listen();
server.AcceptConnections();
client.ConnectToServer();
//for (int i = 0; i < 5; i++) {
// Thread.Sleep(3000);
// server.SendMsg("SENT MSG");
//}
Console.ReadLine();
}
public async void SendMsg(String message) {
try {
NetworkStream networkStream = tcpClient.GetStream();
using (var writer = new StreamWriter(networkStream)) {
await writer.WriteLineAsync(message);
Console.WriteLine("msg sent");
};
} catch (Exception e) {
}
}
private async void KeepAlive(TcpClient tcpClient) {
bool clientConnected = true;
using (NetworkStream networkStream = tcpClient.GetStream())
using (var reader = new StreamReader(networkStream))
using (var writer = new StreamWriter(networkStream)) {
writer.AutoFlush = true;
char keepalive = '0';
while (clientConnected) {
try {
await writer.WriteLineAsync(keepalive);
string dataFromClient = await reader.ReadLineAsync();
Console.WriteLine("Server: " + dataFromClient);
Thread.Sleep(500);
} catch (IOException e){
} catch(ObjectDisposedException e) {
clientConnected = false;
clientsConnected--;
} catch (Exception e){
}
}
}
}
static void Main(字符串[]args)
{
server.Listen();
AcceptConnections();
client.ConnectToServer();
//对于(int i=0;i<5;i++){
//睡眠(3000);
//SendMsg(“sentmsg”);
//}
Console.ReadLine();
}
公共异步void SendMsg(字符串消息){
试一试{
NetworkStream NetworkStream=tcpClient.GetStream();
使用(var writer=newstreamwriter(networkStream)){
等待writer.WriteLineAsync(消息);
Console.WriteLine(“已发送消息”);
};
}捕获(例外e){
}
}
专用异步void KeepAlive(TcpClient TcpClient){
bool clientConnected=true;
使用(NetworkStream NetworkStream=tcpClient.GetStream())
使用(var reader=newstreamreader(networkStream))
使用(var writer=newstreamwriter(networkStream)){
writer.AutoFlush=true;
char keepalive='0';
while(客户端连接){
试一试{
等待编写器。WriteLineAsync(keepalive);
字符串dataFromClient=wait reader.readlinesync();
Console.WriteLine(“服务器:”+dataFromClient);
睡眠(500);
}捕获(IOE异常){
}捕获(ObjectDisposedException e){
clientConnected=false;
客户连接--;
}捕获(例外e){
}
}
}
}
编辑:同时发布我的AcceptConnections方法
public async void AcceptConnections() {
while (true) {
while (clientsConnected <= maxConnections) {
try {
tcpClient = await tcpListener.AcceptTcpClientAsync();
KeepAlive(tcpClient);
} catch (Exception e) {
Console.WriteLine("TOP EXCEPTION :: " + e);
}
clientsConnected++;
Console.WriteLine("SERVER Clients connected: " + clientsConnected);
}
}
}
public异步void AcceptConnections(){
while(true){
while(clients)connected您的SendMsg
方法在StreamWriter
上使用using
。StreamWriter
的默认设置是级联dispose,因此这将关闭NetworkStream
。如果这不是您的意图,您需要将leaveOpen:true
传递到
坦率地说,这里没有理由使用StreamWriter
——我建议直接处理Stream
和Encoding
API。StreamWriter
的一个优点是,它可以在内部为字节[]
重新使用缓冲区,但这是“优点”如果您在处理它之前只使用它进行一次Write
,那么它是没有意义的,并且可以通过缓冲池轻松实现。您没有调用KeepAlive
-我们可以看看它是如何使用的吗?什么调用SendMsg
?请注意,在同一个流上有两个单独的writer(或reader)是非常奇怪和错误的(我在SendMsg
和KeepAlive
中看到编剧)@marcGravel,我将在上面的问题中编辑它,但在AcceptConnections()中调用了KeepAlive).SendMsg是在main方法中调用的,我只是暂时将其注释掉。谢谢,我将尝试使用该构造函数。我想为keepalive ping重用流读取器和写入器,并使用一个单独的读取器和写入器来发送我自己的消息。您认为使用构造函数/仅使用1个读取器/写入器/还是使用流/编码API更好?@IanGlee儿子,你用你开心的东西。我会说:我一直在处理网络和IO代码(这正是我倾向于工作的领域):这里甚至没有一个可以想象的场景,我会在这里使用<代码> StreamReader < /C>或<代码> StreamWriter <代码>。谢谢你的帮助,我有很多事情要考虑。