我试图建立一个可以在彼此之间来回读写信息的客户端和服务器。我可以从客户端和服务器写入读取但不反之亦然,我不知道为什么。这里的任何人似乎都不知道我以前什么时候问过,而且我在网上找不到任何有用的东西。如果您知道,请告诉我,不要告诉我去阅读有关TCP的文章,因为它根本没有帮助。
客户端:
namespace ExampleClient
{
public partial class Form1 : Form
{
public static bool IsConnected;
public static NetworkStream Writer;
public static NetworkStream Receiver;
public Form1()
{
InitializeComponent();
}
private void BtnConnect_Click(object sender, EventArgs e)
{
TcpClient Connector = new TcpClient();
Connector.Connect(TxtIP.Text, Convert.ToInt32(TxtPort.Text));
IsConnected = true;
Writer = Connector.GetStream();
Console.WriteLine("Connected");
System.Threading.Thread Rec = new System.Threading.Thread(new System.Threading.ThreadStart(Receive));
Rec.Start();
}
private void BtnWrite_Click(object sender, EventArgs e)
{
try{
byte[] Packet = Encoding.ASCII.GetBytes("Client Write Test");
Writer.Write(Packet, 0, Packet.Length);
Writer.Flush();}
catch{
try { Writer.Close();} catch { }}
}
public static void Receive()
{
while (true){
try{
byte[] RecPacket = new byte[1000];
Receiver.Read(RecPacket, 0, RecPacket.Length);
Receiver.Flush();
string Message = Encoding.ASCII.GetString(RecPacket);
MessageBox.Show(Message);
}
catch { break;}
}
}
}
}
Receiver / Server:
namespace ExampleServer
{
public partial class Form1 : Form
{
public static NetworkStream Writer;
public static NetworkStream Receiver;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
TcpListener Server = new TcpListener(2002);
Server.Start();
TcpClient Connection = Server.AcceptTcpClient();
Receiver = Connection.GetStream();
System.Threading.Thread Rec = new System.Threading.Thread(new System.Threading.ThreadStart(Receive));
Rec.Start();
}
public static void Receive()
{
while (true)
{
try
{
byte[] RecPacket = new byte[1000];
Receiver.Read(RecPacket, 0, RecPacket.Length);
Receiver.Flush();
string Message = Encoding.ASCII.GetString(RecPacket);
MessageBox.Show(Message);
try{
byte[] Packet = Encoding.ASCII.GetBytes("Server Write Test");
Writer.Write(Packet, 0, Packet.Length);
Writer.Flush();}
catch{
try { Writer.Close(); } catch { }}
}
catch { break; }
}
}
}
}
因此,当服务器从客户端读取消息时,它会显示它正常工作,但是当它将消息写回客户端时,它会因错误而崩溃" system.nullreferenceeexception:未设置对象引用到一个对象的实例。在exampleserver.form1.receive()"。
答案 0 :(得分:1)
您的客户从未收到回复的问题是由于您从未接受过。
您永远不会初始化客户端的Receiver
流,应用程序不会中断,因为 A)错误会在另一个线程中抛出, B )你只是在发生错误时打破while
循环,你真的需要以某种方式记录错误。
仅使用一个NetworkStream
。该流支持同时接收和发送,只有两个以上更容易 - 您不会忘记轻松初始化它。
将来您还应该考虑处理您的消息。由于TCP是基于流的,您可以以任何可能的方式获取消息;消息的三分之一,消息的一半,或一次只有一个字节(等)。有几种方法可以解决这个问题,但最好的方法是长度前缀(或长度前缀)。
长度前缀与标头前缀相结合,使您的信息在接收正确信息时可靠。如果操作正确,您始终可以确保收到包含正确且正确数据量的消息。
长度和标头前缀意味着前缀每条消息的正确长度,以及一个标题,告诉消息的用途。这是它的组成方式:
这将产生以下结构:
[Length (4 bytes)][Header (1 byte)][Message (?? byte(s))]
阅读:
阅读该序列,您将始终知道从另一个端点读取和期望的内容,因此您不会遇到部分或消息被集中在一起的问题。
希望这有帮助!
答案 1 :(得分:0)
每个套接字地址(协议/网络地址/端口)通常只允许使用一种...不要启动TcpListener。
答案 2 :(得分:-1)
我不认为你正在初始化Writer
。确保在调用之前初始化。
你捕获了第一个NullReferenceException,但是在catch中,你再次调用Writer
,抛出一个新的。{/ p>