我有以下这些方法:
private void connectToServer() {
client = new TcpClient(SERVER_IP, PORT_NO);
nwStream = client.GetStream();
writer = new StreamWriter(client.GetStream());
writer.AutoFlush = true;
connected = true;
getDataFromServer();
rtb_inputField.Select();
if (getDataTimer == null) {
getDataTimer = new System.Timers.Timer();
getDataTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
getDataTimer.Interval = 1000;
getDataTimer.Enabled = true;
}
}
private void disconnectFromServer() {
if (connected) {
writer.WriteLine("quit");
getDataTimer.Enabled = false;
getDataTimer.Dispose();
getDataTimer = null;
Thread.Sleep(1000); //Wait 1 second
nwStream.Close();
client.Close();
rtb_outputWindow.AppendText("\n\nClient: Disconnected.");
}
connected = false;
}
private void getDataFromServer() {
if (connected) {
new Thread(() => {
Thread.CurrentThread.IsBackground = true;
byte[] bytesToRead = new byte[client.ReceiveBufferSize];
int readData = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
updateOutputWindow(Encoding.Default.GetString(bytesToRead, 0, readData));
}).Start();
}
}
private void updateOutputWindow(string text) {
string newText = string.Empty;
if (InvokeRequired) {
Invoke(new MethodInvoker(delegate () {
updateOutputWindow(text);
}));
}
else {
newText = startRTFString;
newText += rtb_outputWindow.Rtf;
newText += replaceAnsiColorCodes(text);
rtb_outputWindow.Rtf = newText;
}
}
private void OnTimedEvent(object source, ElapsedEventArgs e) {
if (connected) {
getDataFromServer();
}
}
这一切都正常,但有些地方不对劲。当我断开连接时,outputWindow会得到很多换行符,最后才会说"Client: Disconnected“。我与服务器保持连接的时间越长,断开连接所需的时间就越长。
我相信计时器和这个问题有关。计时器的任务是不断地从服务器请求数据,并在收到数据时将其输出。有没有更好的方法呢?也许“等待服务器发送数据”--如果在几秒钟内什么都没有发送,我就不需要向服务器发送请求了。
getDataFromServer方法中的新线程是否由垃圾收集器处理?或者我需要以某种方式处理它?(这样我就不会创建一大堆后台线程了。)
发布于 2017-08-19 05:07:39
您不需要计时器来监听传入的数据。这应该会自动为您处理。每次调用侦听线程任务时,它都应该获取任何传入的数据,然后完成任务,以便其他线程可以执行。
下面是我的一个项目中的一个听力任务示例。传入的数据是序列化的字符串。
void ListeningObjectTask()// Recieves any data sent by the other user.
{
while (client != null && client.Connected)// If there is another user and they are connected.
{
try// This suppresses exceptions thrown by connection problems, such as the user losing network signal.
{
recieve = str.ReadLine();// Gets the data sent by the other user.
if (recieve != "")// If the user has sent data.
{
lock (recievedStrings)// Locks the buffer to add the data sent by the other user to it.
{
recievedStrings.Enqueue(recieve);
}
recieve = "";// Clears the incoming data, as it has been stored.
}
}
catch (Exception Ex)
{
// Ends all the other multiplayer objects as the connection has ended and they are no longer needed.
Disconnect();
// Tells the user why they have lost connection, so that they can try to fix the problem.
MessageBox.Show("Network connection ended\n" + Ex);
}
}
}
以下是所用对象的声明:
private TcpClient client;// Allows connections for tcp network services.
private StreamReader str; // Provides an interface to read from a stream.
private string recieve;// The incoming string recieved from the other user.
readonly Queue<string> recievedStrings = new Queue<string>();// A buffer to hold incoming data from the other user.
https://stackoverflow.com/questions/45764921
复制相似问题