Google グループは Usenet の新規の投稿と購読のサポートを終了しました。過去のコンテンツは引き続き閲覧できます。
Dismiss

.Net Socket.Send Bug?

閲覧: 3 回
最初の未読メッセージにスキップ

Druid

未読、
2005/10/04 13:44:112005/10/04
To:
Hi, I posted this under the topic "C#"
(http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_frm/thread/eced8551da69d8c2/657848de43ee4a1a?hl=en#657848de43ee4a1a)

But I think it's more appropriate here:


I've got a C# client/service application using a Socket object to
communicate. I have a socket bug that I can't solve without
kludged-code. Does anyone know a more elegant solutions? Is this a
known bug with the .NET Socket object?


Under high stress data sending, I occasionally receive duplicate data
on the server which really throws a wrench into the system. The
duplicate data I receive is always part of the tail end of the last
message sent.


Example:
Message 1: FirstMessage
Message 2: SecondMessage
Message 3: ssage (DUPLICATE BUG!)
Message 4: FourthMessage


I need to eliminate this problem. The only solution I have that works
is to add a Thread.Sleep(10) immediately after Socket.Send(buffer). If

I add that sleep, it works perfectly every time.


I have tried using a NetworkStream instead of a Socket, and I have
tried BeginSend/EndSend and they all demonstrate the exact same
problem.


This only happens when I am sending message very fast in a loop such
as:


for (int i=0; i < 1000; i++)
{
_socket.Send(buffer);

}


or

for (int i=0; i < 1000; i++)
{
// Async way
IAsyncResult asyncSend = _socket.BeginSend(regPackage, 0,
regPackage.Length, System.Net.Sockets.SocketFlags.None, null, null);
_socket.EndSend(asyncSend);

}


or

for (int i=0; i < 1000; i++)
{
SendData(_socket, regPackage);

}


public int SendData(TSSocket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
{
sent = s.Send(data, total, dataleft,
System.Net.Sockets.SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;


}


Again, the only solution that has worked for me is adding a
Thread.Sleep(10), or some other code that keeps the processor busy so
that the Send has time complete. I tried shorter wait times, but 1 or
2 doesn't give enough time, so I played it safer and choose 10.

The is a sample of how I've currently got it working:


for (int i=0; i < 1000; i++)
{
SendData(_socket, buffer);
Thread.Sleep(10);

}


HELP!

Fredster

未読、
2005/10/04 17:30:352005/10/04
To:
Druid,

I solved my problem today. I re-implemented a packet system, and had
to reduce my packets to a 2k size. Which to me, makes my issue clearly
a buffer problem. Now to figure out how to increase the buffers.....

As to your issue, is there any chance you are simply overruning the
receiver? It didn't look like you have any kind of sync methods in
place, and I'm fairly certain a call to receive, while a call is still
executing, will cause a similar type issue to what you are seeing.

While take it for what it's worth, I'm clearly no expert in the world
of sockets...

G'luck to ya...

Fredster

Druid

未読、
2005/10/05 10:13:502005/10/05
To:
Thanks Fredster, I'll look into a new packet system, although how do
you do that with .NET? I see nothing about packet size on the socket
objects. Do you have to use Windows API calls? As far as sync
methods, I have methods on the server that handle partial messages and
builds them so that if I get a partial message I don't process it, but
wait for the next one to come in and pre-pend the partial message on
it. That seems to be working fine, is that what you mean when you say
"sync methods"? Thanks for the help, I'll let you know if I get it
working without a sleep and what I did.

Druid

未読、
2005/10/07 18:54:482005/10/07
To:
I made a sample program that demonstres the problem. Anbody should be
able to copy-paste and run this code to re-create the problem. Look
near the end for my comment: "WHY DO I NEED THIS SLEEP?". If I don't
have a sleep the data does not come across properly.

To run this, start two EXEs. Click "Start Server" on the one, then
"Start Client" on the other, then click "Send 100 messages" on the
client.

Try it with the sleep commented in and then out and you will see that
you get different data! Sure looks like a .NET socket object bug to
me. Can anybody get this to work without the sleep?

Create a Windows Application and put this code in it:


using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace SocketServerSpeedTest
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private TcpListener _serverListener = new TcpListener(2345);
Socket _connectedSocket = null;
private Socket _clientSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
private static int Counter = 1;

private System.Windows.Forms.Button btnStartServer;
private System.Windows.Forms.Button btnStartClient;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button btnSendMessages;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStartServer = new System.Windows.Forms.Button();
this.btnStartClient = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.btnSendMessages = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStartServer
//
this.btnStartServer.Location = new System.Drawing.Point(80, 24);
this.btnStartServer.Name = "btnStartServer";
this.btnStartServer.Size = new System.Drawing.Size(120, 23);
this.btnStartServer.TabIndex = 0;
this.btnStartServer.Text = "Start Server";
this.btnStartServer.Click += new
System.EventHandler(this.btnStartServer_Click);
//
// btnStartClient
//
this.btnStartClient.Location = new System.Drawing.Point(80, 64);
this.btnStartClient.Name = "btnStartClient";
this.btnStartClient.Size = new System.Drawing.Size(120, 23);
this.btnStartClient.TabIndex = 0;
this.btnStartClient.Text = "Start Client";
this.btnStartClient.Click += new
System.EventHandler(this.btnStartClient_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(16, 144);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.textBox1.Size = new System.Drawing.Size(256, 120);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "";
//
// btnSendMessages
//
this.btnSendMessages.Enabled = false;
this.btnSendMessages.Location = new System.Drawing.Point(80, 104);
this.btnSendMessages.Name = "btnSendMessages";
this.btnSendMessages.Size = new System.Drawing.Size(120, 23);
this.btnSendMessages.TabIndex = 2;
this.btnSendMessages.Text = "Send 100 messages";
this.btnSendMessages.Click += new
System.EventHandler(this.btnSendMessages_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.btnSendMessages);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.btnStartServer);
this.Controls.Add(this.btnStartClient);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void btnStartServer_Click(object sender, System.EventArgs e)
{
btnStartClient.Enabled = false;
btnSendMessages.Enabled = false;

// the receive buffer
byte[] buffer = new byte[100];

_serverListener.Start();

_connectedSocket = _serverListener.AcceptSocket();
_connectedSocket.BeginReceive(buffer, 0, buffer.Length,
SocketFlags.None, new AsyncCallback(myCallback), buffer);
}

private void myCallback(IAsyncResult ar)
{
Console.WriteLine("[RemoteSocketRead]");

byte[] buffer = (byte[])ar.AsyncState;

string message = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
this.textBox1.Text = this.textBox1.Text + " " + message;

_connectedSocket.BeginReceive(buffer, 0, buffer.Length,
SocketFlags.None, new AsyncCallback(myCallback), buffer);
}

private void btnStartClient_Click(object sender, System.EventArgs e)
{
this.btnStartServer.Enabled = false;
this.btnSendMessages.Enabled = true;

EndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2345);
_clientSocket.Connect(ep);
}

private void btnSendMessages_Click(object sender, System.EventArgs e)
{
for (int i=0; i < 100; i++)
{
string currentValue = Counter.ToString();
byte[] byteArrayToSend = Encoding.ASCII.GetBytes(currentValue);
_clientSocket.Send(byteArrayToSend);

// WHY DO I NEED THIS SLEEP? THE DATA WILL NOT BE CORRECT WITHOUT
IT!
System.Threading.Thread.Sleep(100);

Counter++;
}
}
}
}

Ice

未読、
2005/11/02 18:49:192005/11/02
To:
i'm sorry, but my newsreader chopped up part of this message. what is the
original issue.

ice
"Druid" <matt...@gmail.com> wrote in message
news:1128725688.6...@o13g2000cwo.googlegroups.com...

新着メール 0 件