在发送的TCP消息之间延迟(在接收方),发送方没有延迟 [英] Delays (at recipient) between TCP messages that are sent with no delays from sender

查看:116
本文介绍了在发送的TCP消息之间延迟(在接收方),发送方没有延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问候。

我有一个非常简单的客户端/服务器应用程序。我已经开发了这个,因为我在一个*正在开发的*简单应用程序中看到了一些奇怪的TCP行为,但我已经能够至少隔离它并使其在示例应用程序中可重现。
< br>基本上,我的客户端应用程序创建了一个TcpClient实例,传入服务器的IP和端口。连接后,它会产生一个永远循环的新线程,从服务器读取数据。收到数据后,它会打印到屏幕上。足够简单。

在服务器端,它创建一个TcpListener,每当客户端连接时,它还会创建一个与客户端完全相同的接收线程,监听消息。

我有能力从任何一方发送消息 - 就像聊天程序一样。然而,我注意到的是,如果我按顺序发送两个消息(没有延迟),则消息之间的接收方有〜150ms的延迟。正如我所说,这正在我正在开发的一个更大的应用程序中出现,但我已经能够将它减少到这个小应用程序。

如果我发送两个回复,那么更奇怪的是 - 在建立连接后立即*返回消息*(例如,客户端连接到服务器,此时服务器立即响应2条消息)延迟不存在!但是,如果稍后我发送了两条关于此"陈旧"消息的消息。但是,TCP连接存在延迟。我正在附加客户端和服务器的完整源代码。任何帮助都非常感谢。

谢谢!
Rick

服务器代码:

Greetings.

I have a very simple client/server application.  I've developed this because I'm seeing some strange TCP behavior in a *less* simple application I'm developing, but I've been able to at least isolate it and make it reproducible in a sample app.

Basically, my Client application creates an instance of TcpClient, passing in the IP and port of the server.  Once connected, it spawns a new thread that forever loops, reading data from the server.  When data is received, it prints to the screen.  Simple enough.

On the Server side, it creates a TcpListener, whenever a client connects, it also creates a receive thread that does exactly the same thing as the client, listening for messages.

I have the ability to send a message from either side -- like a chat program.  What I'm noticing, however, is if I send two messages sequentially (with no delay) there is a ~150ms delay on the recipient side in between messages.  This is showing up, as I said, in a much larger application I'm developing, but I've been able to reduce it to this small app.

What's even stranger is if I send the two back-to-back messages *immediately* after the connection is made (e.g. the client connects to the server, at this very moment the server immediately responds with 2 messages) the delay is not present!  If, however, later on I send two messages on this "stale" TCP connection, however, the delay is present.  I'm attaching the complete source code for both the client and the server.  Any help is GREATLY appreciated.

Thanks!
Rick

Server Code:

< tbody> < tr> < td style ="background-color:rgb(247,247,247)"> if (InvokeRequired){
使用 系统;
使用 < font style ="font-size:11px"> System.Collections.Generic;
使用 System.Collections;
使用 < font style ="font-size:11px"> System.Data;
使用 System.Windows.Forms ;
使用 < font style ="font-size:11px"> System.IO;
使用 System.Threading;
使用 < font style ="font-size:11px"> System.Net.Sockets;
namespace NetworkTest
{
public ServerForm:Form
{
protected NetworkStream m_Stream = null ;
委托 < font style ="color:blue"> void AddToWindowCallback( string TOADD);
public < font style ="font-size:11px"> ServerForm()
{
InitializeComponent();
线程tcpListenerThread = new 线程( new ThreadStart(run));
tcpListenerThread.Start();
}
受保护 void run()
{
TcpListener listener = new TcpListener(3839);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
Byte [] data = < font style ="color:blue"> new Byte [3000];
int bytes = client.GetStream ().Read(数据1,0,data.Length);
string < font style ="font-size:11px"> message = System.Text.Encoding.ASCII.GetString(data,0,bytes);
if (message.Contains( " CONNECT" )){
m_Stream = client.GetStream();
byte [] data2 = System.Text.Encoding .ASCII.GetBytes( " Connected。" );
client.GetStream()。Write(data2,0,data2.Length) ;
线程receiveThread = new 线程( new ThreadStart(RunTcpReceiveLoop));
receiveThread.Start();
}
}
protected void RunTcpReceiveLoop()
{
string completeMessage = "" ;
while < font style ="font-size:11px">( true ){
尝试 {
if (m_Stream.CanRead){
Byte [] data = new 字节[3000];
int < font style ="font-size:11px"> bytes = m_Stream.Read(data,0,data.Length);
if (bytes> 0){
completeMessage + = System.Text.Encoding.ASCII.GetString(数据,0,字节);
int firstIndex = completeMessage.IndexOf('@');
while < font style ="font-size:11px">(firstIndex> = 0){
string nextMessage = completeMessage.Substring(0,firstIndex);
AddToWindow(nextMessage);
completeMessage = completeMessage.Remove(0,firstIndex + 1);
firstIndex = completeMessage.IndexOf('@');
}
}
}
} catch (Exception ex){
AddToWindow("套接字错误:" + ex.Message + " \ n" + ex.StackTrace);
}
}
}
私人 void sendButton_Click( object sender,EventArgs e)
{
if (m_Stream!= null ){
string response1 = "来自服务器的消息。" ;
byte [] data1 = System .Text.Encoding.ASCII.GetBytes(响应1);
m_Stream.Write(data1,0,data1.Length);
m_Stream.Write(DATA1,0,data1.Length);
}
}
public void AddToWindow( string toAdd)
{
AddToWindowCallback d = new AddToWindowCallback(AddToWindow );
调用(d, new object [] {toAdd });
} else {
outputTextBox.Text + = toAdd + " \\\
"
;
}
}
private void InitializeComponent()
{
.sendButton = new System.Windows.Forms.Button();
< font style ="font-size:11px">。outputTextBox = new System.Windows.Forms .RichTextBox();
。SuspendLayout();
//
// sendButton
//
这个 .sendButton.Location = new System.Drawing.Point(12,12);
< font style ="font-size:11px"> .sendButton.Name = " sendButton" ;
.sendButton.Size = new System.Drawing.Size(75,23);
< font style ="font-size:11px"> .sendButton.TabIndex = 0;
.sendButton.Text = " button1" ;
< font style ="font-size:11px"> .sendButton.UseVisualStyleBackColor = true ;
.sendButton.Click + = new System.EventHandler( .sendButton_Click);
//
// outputTextBox
//
这个 。outputTextBox.Anchor =((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms .AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
.outputTextBox.Location = new System.Drawing.Point(12 ,41);
。outputTextBox.Name = " outputTextBox" ;
< font style ="font-size:11px">。outputTextBox.Size = new System.Drawing .Size(247,206);
。outputTextBox.TabIndex = 5;
< font style ="font-size:11px">。outputTextBox.Text = "" ;
//
// ServerForm
//
this 。AutoScaleDimensions = new System.Drawing.SizeF(6F,13F);
。AutoScaleMode = System。 Windows.Forms.AutoScaleMode.Font;
< font style ="font-size:11px"> .ClientSize = new System.Drawing.Size (292,273);
.Controls.Add( 。outputTextBox);
< font style ="font-size:11px"> .Controls.Add( this .sendButton) ;
.Name = " ServerForm" ;
< font style ="font-size:11px">。Text = " ServerForm" ;
。ResumeLayout( false );
}
private 按钮sendButton;
private RichTextBox outputTextBox;
}
}
using System; 
using System.Collections.Generic; 
using System.Collections; 
using System.Data; 
using System.Windows.Forms; 
using System.IO; 
using System.Threading; 
using System.Net.Sockets; 
  
namespace NetworkTest 
    public class ServerForm : Form 
    { 
        protected NetworkStream m_Stream = null
        delegate void AddToWindowCallback(string toAdd); 
        public ServerForm() 
        { 
            InitializeComponent(); 
            Thread tcpListenerThread = new Thread(new ThreadStart(run)); 
            tcpListenerThread.Start(); 
        }         
        protected void run() 
        { 
            TcpListener listener = new TcpListener(3839); 
            listener.Start(); 
            TcpClient client = listener.AcceptTcpClient(); 
  
            Byte[] data = new Byte[3000]; 
            int bytes = client.GetStream().Read(data, 0, data.Length); 
            string message = System.Text.Encoding.ASCII.GetString(data, 0, bytes); 
            if (message.Contains("CONNECT")) { 
                m_Stream = client.GetStream(); 
                byte[] data2 = System.Text.Encoding.ASCII.GetBytes("Connected."); 
                client.GetStream().Write(data2, 0, data2.Length); 
                Thread receiveThread = new Thread(new ThreadStart(RunTcpReceiveLoop)); 
                receiveThread.Start(); 
            } 
        } 
        protected void RunTcpReceiveLoop() 
        { 
            string completeMessage = ""
            while (true) { 
                try { 
                    if (m_Stream.CanRead) { 
                        Byte[] data = new Byte[3000]; 
                        int bytes = m_Stream.Read(data, 0, data.Length); 
  
                        if (bytes > 0) { 
                            completeMessage += System.Text.Encoding.ASCII.GetString(data, 0, bytes); 
  
                            int firstIndex = completeMessage.IndexOf('@'); 
                            while (firstIndex >= 0) { 
                                string nextMessage = completeMessage.Substring(0, firstIndex); 
                                AddToWindow(nextMessage); 
                                completeMessage = completeMessage.Remove(0, firstIndex + 1); 
                                firstIndex = completeMessage.IndexOf('@'); 
                            } 
                        } 
                    } 
                } catch (Exception ex) { 
                    AddToWindow("socket error: " + ex.Message + "\n" + ex.StackTrace); 
                } 
            } 
        } 
        private void sendButton_Click(object sender, EventArgs e) 
        { 
            if (m_Stream != null) { 
                string response1 = "Message from server."
                byte[] data1 = System.Text.Encoding.ASCII.GetBytes(response1); 
                m_Stream.Write(data1, 0, data1.Length); 
                m_Stream.Write(data1, 0, data1.Length); 
            } 
        } 
        public void AddToWindow(string toAdd) 
        { 
            if (InvokeRequired) { 
                AddToWindowCallback d = new AddToWindowCallback(AddToWindow); 
                Invoke(d, new object[] { toAdd }); 
            } else { 
                outputTextBox.Text += toAdd + "\n"
            } 
        } 
        private void InitializeComponent() 
        { 
            this.sendButton = new System.Windows.Forms.Button(); 
            this.outputTextBox = new System.Windows.Forms.RichTextBox(); 
            this.SuspendLayout(); 
            //  
            // sendButton 
            //  
            this.sendButton.Location = new System.Drawing.Point(12, 12); 
            this.sendButton.Name = "sendButton"
            this.sendButton.Size = new System.Drawing.Size(75, 23); 
            this.sendButton.TabIndex = 0; 
            this.sendButton.Text = "button1"
            this.sendButton.UseVisualStyleBackColor = true
            this.sendButton.Click += new System.EventHandler(this.sendButton_Click); 
            //  
            // outputTextBox 
            //  
            this.outputTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                        | System.Windows.Forms.AnchorStyles.Left) 
                        | System.Windows.Forms.AnchorStyles.Right))); 
            this.outputTextBox.Location = new System.Drawing.Point(12, 41); 
            this.outputTextBox.Name = "outputTextBox"
            this.outputTextBox.Size = new System.Drawing.Size(247, 206); 
            this.outputTextBox.TabIndex = 5; 
            this.outputTextBox.Text = ""
            //  
            // ServerForm 
            //  
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
            this.ClientSize = new System.Drawing.Size(292, 273); 
            this.Controls.Add(this.outputTextBox); 
            this.Controls.Add(this.sendButton); 
            this.Name = "ServerForm"
            this.Text = "ServerForm"
            this.ResumeLayout(false); 
  
        } 
        private Button sendButton; 
        private RichTextBox outputTextBox;         
    } 

推荐答案

我对这个感兴趣,可能会看看我是不是能得到它明天某个时候在测试系统上运行......
I'm interested in this one and may see if I can't get it running on a test system tomorrow sometime...


这篇关于在发送的TCP消息之间延迟(在接收方),发送方没有延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆