我有一个使用tcpclient的连接,在服务器和客户端之间发送和接收数据。该应用程序是基于Window Form编写的,我使用BackgroundWorker来处理并行运行的任务。当我点击开始按钮时,程序正常运行,它从客户端接收数据握手并将数据发送回客户端。我想增加一个功能,从文本框发送新的内容,如样本填写数据到Textbox 1,并单击发送按钮,它将被发送到客户端从服务器在服务器和客户端之间的连接并行。但是当我添加这个时,我得到一个错误,返回“Cannot access a disposed object.对象名称:System.Net.Sockets.NetworkStream”at this line“stream.Write(msg_byte,0,msg_byte.Length);”并且不发送数据。我做错了什么,你能指给我看吗?这是我下面的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace Server
{
public partial class Form1 : Form
{
BackgroundWorker bw;
static NetworkStream stream = null;
public Form1()
{
InitializeComponent();
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
}
private void _startServer(string _ip, int _port)
{
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Parse(_ip), _port);
server.Start();
Byte[] bytes = new Byte[1024];
String data = null;
while (true)
{
TcpClient client = server.AcceptTcpClient();
txt_log.Invoke((Action)(() =>
{
txt_log.AppendText(DateTime.Now.ToString() + " Connnected " + client.Client.RemoteEndPoint.ToString() + "\r\n");
}));
data = null;
NetworkStream stream = client.GetStream();
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = Encoding.ASCII.GetString(bytes, 0, i);
txt_log.Invoke((Action)(() =>
{
txt_log.AppendText(DateTime.Now.ToString() + " Received: " + data + "\r\n");
}));
data = data.ToUpper();
byte[] msg = Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
txt_log.Invoke((Action)(() =>
{
txt_log.AppendText(DateTime.Now.ToString() + " Sent: " + data + "\r\n");
}));
}
}
}
catch (SocketException ex)
{
MessageBox.Show("_startServer: " + ex.Message);
}
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("completed");
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (!bw.CancellationPending)
{
MessageBox.Show("processing");
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
_startServer("192.168.10.15", 4444);
bw.ReportProgress(100);
}
private void bt_start_Click(object sender, EventArgs e)
{
if (bw.IsBusy)
{
bw.CancelAsync();
}
else
{
txt_log.Clear();
bw.RunWorkerAsync();
}
}
private void bt_stop_Click(object sender, EventArgs e)
{
bw.CancelAsync();
if (stream != null)
{
stream.Dispose();
}
}
private void bt_send_Click(object sender, EventArgs e)
{
string msg_send = txt_msg.Text;
byte[] msg_byte = Encoding.ASCII.GetBytes(msg_send);
while (true)
{
stream.Write(msg_byte, 0, msg_byte.Length);
txt_log.Invoke((Action)(() =>
{
txt_log.AppendText(DateTime.Now.ToString() + " Sent new data: " + msg_send + "\r\n");
}));
string msg_receive = null;
byte[] temp_byte = new byte[1024];
stream.Read(temp_byte, 0, temp_byte.Length);
msg_receive = Encoding.ASCII.GetString(temp_byte);
txt_log.Invoke((Action)(() =>
{
txt_log.AppendText(DateTime.Now.ToString() + " Received new data: " + msg_receive + "\r\n");
}));
}
}
}
}
这种情况是从客户端打开到服务器的连接,一方面,总是通过不断发送临时数据来保持从服务器到客户端的连接,就像客户端总是发送“你在吗?”服务器总是回答“好的,我在这里”当从客户端得到信号数据临时,这种方式对我来说很好,没有问题。另一方面,我想有其他信号从服务器发送到客户端根据什么用户进入文本框组件,我只是尝试和思考最好的方式来做到这一点。
经过一些更改后,make代码看起来更容易
private string IsRealData(byte[] data)
{
string txt = "";
if (data[10] == 100)
txt = "are you there?";
else
txt = "NOTHING";
return txt;
}
private void _startServer(string _ip, int _port)
{
TcpListener server = null;
try
{
server = new TcpListener(IPAddress.Parse(_ip), _port);
server.Start();
byte[] bytes = new Byte[1024];
while (true)
{
TcpClient client = server.AcceptTcpClient();
String data = null;
NetworkStream stream = client.GetStream();
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = Encoding.ASCII.GetString(bytes, 0, i);
byte[] bytes_real = new byte[i];
Buffer.BlockCopy(bytes, 0, bytes_real, 0, i);
if (IsRealData(bytes_real) == "are you there?")
{
string _msg_reply = "ok, here I am";
byte[] reply = Encoding.ASCII.GetBytes(_msg_reply);
stream.Write(reply, 0, reply.Length); ///sent real data to client
txt_log.Invoke((Action)(() =>
{
txt_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff tt") + " Sent: " + _msg_reply + "\r\n");
}));
}
else
{
data = data.ToUpper();
byte[] msg = Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length); ///sent temporary data to client
}
}
}
}
catch (SocketException ex)
{
MessageBox.Show("_startServer: " + ex.Message);
}
}
private async Task Start_Server()
{
await Task.Run(() =>
{
_startServer("192.168.10.15", 4444);
});
}
private void bt_start_Click(object sender, EventArgs e)
{
Start_Server();
}
private void bt_send_Click(object sender, EventArgs e)
{
string text = txt_msg.Text;
////how to send content parallel when user input from Textbox component
}
谢谢大家。
1条答案
按热度按时间aor9mmx11#
经过一些调试和改进,现在它可以为我工作了.注意,我刚刚在最后的代码中做了一些改动,在服务器和客户端之间建立了连接套接字的基础上,给予了这个套接字对象并使用send/receive。就这样
谢谢大家的建议。