我正在编写一个SMTP服务器作为学习TCP socketing的练习。
我遇到了障碍,我需要通过检测缓冲区中是否存在<CRLF>.<CRLF>
来退出ReadBlock。连接到SMTP服务器的客户端将使用<CRLF>.<CRLF>.
但是,我不知道处理此问题的最佳方法。
我可以编写一个定时查看<CRLF>.<CRLF>
当前缓冲区的计时器,但这对我来说似乎效率低下。
通过检测<CRLF>.<CRLF>
private static void Service()
{
while (true)
{
var theSocket = _listener.AcceptSocket();
Console.WriteLine("Connected: {0}",theSocket.RemoteEndPoint);
try
{
Stream s = new NetworkStream(theSocket);
var socketReader = new StreamReader(s);
var socketWriter = new StreamWriter(s) {AutoFlush = true};
socketWriter.WriteLine("Hello {0}",theSocket.RemoteEndPoint);
using (var fileWriter = new StreamWriter(@"E:\test\tmp.txt",true))
{
do
{
fileWriter.WriteLine(theSocket.RemoteEndPoint);
char[] buf = new char[40];
int read = socketReader.ReadBlock(buf, 0, 40);
while (read != 0)
{
fileWriter.Write(buf,0,read);
fileWriter.WriteLine();
read = socketReader.ReadBlock(buf, 0, 40);
}
} while (true);
}
s.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Disconnected: " + theSocket.RemoteEndPoint);
theSocket.Close();
}
}
答案 0 :(得分:0)
ReadBlock
不阻止读取。它将立即返回,最多可达到呼叫中指定的最大字符数(在您的情况下为40)。
该方法将阻塞,直到读取计数字符或已到达流的末尾。这是Read的阻止版本。
http://msdn.microsoft.com/en-us/library/system.io.streamreader.readblock(v=vs.110).aspx
一旦呼叫返回,您只需根据需要检查缓冲区的CRLF。
或者根据评论中的建议,ReadLine()可能适合您的需要。