我有一个套接字连接,并且通过这个套接字发送数据。我连接的服务器会回复我的数据的每一个正确的发送。我收到了该消息,因此我收到了每封邮件的答案。有时候服务器喜欢保留一段消息几秒钟,或者按照不同的顺序发送消息。我的解决方案是产生一个线程,让它绕接收函数旋转。但是,使用MSDN上的套接字示例,我有适合。他们使用简单的do/while循环结构。当我这样做时,我得到了混乱的回复,和/或不完整的数据。这是为了做家庭作业,所以我必须手工编写客户端,而不是仅仅使用更简单的解决方案。这个代码可能有问题吗?我在它的眼前这么久,我觉得我失去了一些东西简单:C#套接字接收线程
private static void ReceiveThread(Socket sock, ReceiverClass rc)
{
// Create a socket and pass in parameter converted from object socket
int receivedBytes = 0;
do
{
// receive data from socket
receivedBytes = sock.Receive(rc.buffer);
byte[] formattedMsg = new byte[receivedBytes];
Array.Copy(rc.buffer, formattedMsg, receivedBytes);
rc.sb.Append("<LF><CR>" + System.Text.Encoding.ASCII.GetString(formattedMsg) + "\r\n");
}
while (receivedBytes > 0);
}
编辑,并称滋生接收线程功能。 (这是太长时间,但我打算使它敢时,我得到了愚蠢的事情工作):
public void SendData(Socket sock)
{
// Set socket timeout
sock.ReceiveTimeout = 4000;
// Prepare file for IO operations
string path = @"c:\Logs\Lab2.Scenario3.WurdingerO.txt";
StreamWriter logWrite = File.AppendText(path);
// Get local ip address:
IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => address.AddressFamily == AddressFamily.InterNetwork).First();
string portNum = ((IPEndPoint)sock.LocalEndPoint).Port.ToString();
// response time for scenario 2 and 3
int responseTime = 0;
// Set up Stopwatch to keep track of time
Stopwatch stpWatch = new Stopwatch();
stpWatch.Start();
// setup for logging class
ReceiverClass rc = new ReceiverClass();
// setup receiving thread
Thread receiveThread = new Thread(delegate()
{
ReceiveThread(sock, rc);
});
receiveThread.Start();
// Counter to call client operations
for (int i = 0; i < MESSAGE_COUNT; i++)
{
string msTime = Convert.ToString(stpWatch.ElapsedMilliseconds);
if (msTime.Length > 10)
{
string newMSTime = "";
for (int t = 9; t >= 0; t++)
{
newMSTime += msTime[t];
}
msTime = newMSTime;
}
Classes.RequestBuilder reqB = new Classes.RequestBuilder();
byte[] sendMsg;
switch (scenarioNo)
{
case 1:
sendMsg = reqB.MessageBuildScenarioOne(sock, msTime,
ip.ToString(), portNum, serverPort, serverIP, i);
break;
case 2:
// set up response time delay
switch (i)
{
case 1:
responseTime = 1000;
break;
case 3:
responseTime = 3000;
break;
default:
responseTime = 0;
break;
}
sendMsg = reqB.MessageBuildScenarioTwo(sock, msTime,
ip.ToString(), portNum, serverPort, serverIP, i, responseTime);
break;
case 3:
// set up response time delay
switch (i)
{
case 1:
responseTime = 1000;
break;
case 3:
responseTime = 3000;
break;
default:
responseTime = 0;
break;
}
sendMsg = reqB.MessageBuildScenarioThree(sock, msTime,
ip.ToString(), portNum, serverPort, serverIP, i, responseTime);
break;
default:
sendMsg = reqB.MessageBuildScenarioOne(sock, msTime,
ip.ToString(), portNum, serverPort, serverIP, i);
break;
}
try
{
sock.Send(sendMsg);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
// Socket shutdown
sock.Shutdown(SocketShutdown.Send);
receiveThread.Join();
sock.Shutdown(SocketShutdown.Receive);
string date = System.DateTime.Now.ToString("MMddyyyy");
string time = System.DateTime.Now.ToString("HHmmss");
logWrite.Write(rc.sb.ToString());
logWrite.Write(date + "|" + time + "|0|0|");
// Close log file
logWrite.Close();
System.Windows.Forms.MessageBox.Show("Finished");
}
编辑: 我把睡眠计时器在发送操作后,并且固定我跑的问题成。 谢谢!
构建它们时,套接字类型或协议是什么? – Ribose 2013-05-11 22:21:05
你的代码似乎没问题,但不知道代码的其他部分,这很难回答。 – I4V 2013-05-11 22:42:30
“我在发送操作之后放置了一个睡眠定时器,并解决了问题”可能不是固定的。睡眠掩盖了这个问题,所以在99%的情况下它不会发生。它仍然会以1%的速度失败,因为它看起来像是比赛条件。 – usr 2013-05-12 10:30:16