在c#套接字中从服务器获取异常
本文关键字:服务器 获取 异常 套接字 | 更新日期: 2023-09-27 18:14:39
我用c#创建了一个简单的服务器和客户端程序。服务器将发送一个字符串数组到客户端,客户端将显示它,客户端将发送一个id到服务器,服务器将显示它。我的示例代码如下所示。当我运行它们时,我在服务器端得到一个异常。我已经标记了得到异常的行。我的示例代码如下:
服务器:using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace server
{
class Program
{
static void Main(string[] args)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 1234);
tcpListener.Start();
while (true)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
byte[] data = new byte[1024];
NetworkStream ns = tcpClient.GetStream();
string[] arr1 = new string[] { "one", "two", "three" };
var serializer = new XmlSerializer(typeof(string[]));
serializer.Serialize(tcpClient.GetStream(), arr1);
tcpClient.Close();
int recv = ns.Read(data, 0, data.Length); //getting exception in this line
string id = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(id);
}
}
}
}
客户:using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace Client
{
class Program
{
static void Main(string[] args)
{
try
{
byte[] data = new byte[1024];
string stringData;
TcpClient tcpClient = new TcpClient("127.0.0.1", 1234);
NetworkStream ns = tcpClient.GetStream();
var serializer = new XmlSerializer(typeof(string[]));
var stringArr = (string[])serializer.Deserialize(tcpClient.GetStream());
foreach (string s in stringArr)
{
Console.WriteLine(s);
}
string input = Console.ReadLine();
ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length);
ns.Flush();
}
catch (Exception e)
{
Console.Write(e.Message);
}
Console.Read();
}
}
}
我得到的例外是:
An unhandled exception of type 'System.ObjectDisposedException' occurred in System.dll
Additional information: Cannot access a disposed object.
代码有什么问题吗?我需要做些什么来避免这个异常?
在我看来,在您的服务器代码中,您在继续读取数据之前关闭TCP客户端。这就是你得到异常的原因。
同样,你正在尝试读取1024字节,但是客户端没有发送1024字节(除非客户端发送的字符串是来自用户的输入被编码成1024字节数组的可能性不大),所以服务器将简单地阻塞并且什么也不做,因为它正在等待客户端发送1024字节。
管理从/到流读写数据的一个好方法是通过BinaryReader和BinaryWriter类。
考虑以下代码来解决您的问题(它包含对您的代码的一些改进):
服务器:class Program
{
static void Main(string[] args)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 1234);
tcpListener.Start();
while (true)
{
using (TcpClient tcpClient = tcpListener.AcceptTcpClient())
{
using (var network_stream = tcpClient.GetStream())
{
using (BinaryReader reader = new BinaryReader(network_stream))
{
using (BinaryWriter writer = new BinaryWriter(network_stream))
{
string[] arr1 = new string[] { "one", "two", "three" };
writer.Write(arr1.Length);
foreach (var item in arr1)
{
writer.Write(item);
}
var id = reader.ReadString();
Console.WriteLine("Id: " + id);
}
}
}
}
}
}
}
客户:class Program
{
static void Main(string[] args)
{
try
{
using (TcpClient tcpClient = new TcpClient("127.0.0.1", 1234))
{
using (NetworkStream network_stream = tcpClient.GetStream())
{
using (BinaryReader reader = new BinaryReader(network_stream))
{
using (BinaryWriter writer = new BinaryWriter(network_stream))
{
int number_of_strings = reader.ReadInt32();
string[] lines = new string[number_of_strings];
for(int i = 0 ; i < number_of_strings ; i++)
{
lines[i] = reader.ReadString(); //Store the strings if you want to
Console.WriteLine(lines[i]);
}
Console.WriteLine("Please input id:");
string id = Console.ReadLine();
writer.Write(id);
}
}
}
}
}
catch (Exception e)
{
Console.Write(e.Message);
}
Console.Read();
}
}
在您拥有Closed
和TcpClient
(处置它)之后,您正在使用NetworkStream
。
while (true)
{
var tcpClient = tcpListener.AcceptTcpClient();
var data = new byte[1024];
var arr1 = new string[] { "one", "two", "three" };
var serializer = new XmlSerializer(typeof(string[]));
serializer.Serialize(tcpClient.GetStream(), arr1);
var ns = tcpClient.GetStream();
var recv = ns.Read(data, 0, data.Length); //getting exception in this line
var id = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(id);
ns.Close();
tcpClient.Close();
}
tcpClient实现不可能的接口,最好在tcpClient中调用dispose方法
tcpClient.Dispose();
其他tcpClient.GetStream().Close();
tcpClient.Close();
关闭客户端不会关闭流。
var serializer = new XmlSerializer(typeof(string[]));
serializer.Serialize(tcpClient.GetStream(), arr1);
tcpClient.GetStream().Close()
tcpClient.Close();