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!
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
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
"Druid" <matt...@gmail.com> wrote in message
news:1128725688.6...@o13g2000cwo.googlegroups.com...