我有一個套接字連接,並且通過這個套接字發送數據。我連接的服務器會回覆我的數據的每一個正確的發送。我收到了該消息,因此我收到了每封郵件的答案。有時候服務器喜歡保留一段消息幾秒鐘,或者按照不同的順序發送消息。我的解決方案是產生一個線程,讓它繞接收函數旋轉。但是,使用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