我有一个套接字连接,我正在通过这个套接字发送数据。我连接的服务器会回答我数据的每一次正确发送。我的消息正常工作,所以我收到的每条消息都会得到答复。有时服务器喜欢将消息保留几秒钟,或者以不同的顺序发送。我的解决方案是产生一个线程并让它围绕接收函数旋转。但是,使用 MSDN 上的 Sockets 示例我很适合。他们使用简单的 do/while 循环结构。当我这样做时,我会收到混乱的回复和/或不完整的数据。这是一个家庭作业,所以我必须手动编写客户端,而不仅仅是使用更简单的解决方案。这段代码可能有问题吗?我一直盯着它这么久,我想我错过了一些简单的东西:
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");
}
编辑:我在发送操作后放置了一个睡眠定时器,这解决了我遇到的问题。谢谢!