我一直在用C#试验UDP发送和接收,并且有一个奇怪的问题。代码在控制台应用程序中工作正常,但当我尝试在服务中使用完全相同的代码时,client.ceceive方法被阻止。服务正常运行并且不会中止,我有记录写入文本文件,所以我知道它到达接收。有人有主意吗?代码如下......
public partial class Service1 : ServiceBase
{
private bool serviceStarted = false;
Thread listenerThread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
serviceStarted = false;
WriteLog("UDPListener Service Starting");
ThreadStart thread = new ThreadStart(StartListening);
listenerThread = new Thread(thread);
serviceStarted = true;
listenerThread.Start();
}
protected override void OnStop()
{
WriteLog("UDPListener Service Stopping");
serviceStarted = false;
listenerThread.Join(new TimeSpan(0, 0, 5));
}
private void StartListening()
{
WriteLog("Worker thread spawned.");
UdpClient client = new UdpClient(40000);
while (serviceStarted)
{
WriteLog("Service is started. Getting endpoint.");
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 40000);
WriteLog("Thread is listening...");
byte[] content = client.Receive(ref remoteIPEndPoint);
WriteLog("Receive unblocked.");
if (content.Length > 0)
{
string message = Encoding.ASCII.GetString(content);
WriteLog("UDPListener Message = " + message);
}
}
Thread.CurrentThread.Abort();
}
private void WriteLog(string strMessage)
{
FileStream filestream = new FileStream(@"c:\temp\UDPClientLog.txt",
FileMode.OpenOrCreate,
FileAccess.Write);
StreamWriter streamwriter = new StreamWriter(filestream);
streamwriter.BaseStream.Seek(0, SeekOrigin.End);
streamwriter.WriteLine(DateTime.Now.ToLongDateString() +
" at " +
DateTime.Now.ToLongTimeString() +
": " +
strMessage +
"\n");
streamwriter.Flush();
streamwriter.Close();
}
}
答案 0 :(得分:7)
终于弄明白了。 Windows防火墙阻止了传入连接,显然该服务不允许以交互方式请求取消阻止它的权限。
答案 1 :(得分:0)
那是因为UdpClient.Receive阻塞(即同步)操作,并且线程将被阻塞,直到您收到数据:
Receive方法将阻塞,直到数据报从远程主机到达。当数据可用时,Receive方法将读取第一个排队的数据报并将数据部分作为字节数组返回。此方法使用发件人的IPAddress和端口号填充remoteEP参数。
如果您想要非阻止行为,可以使用异步版本:UdpClient.BeginReceive方法。
答案 2 :(得分:0)
而不是关闭窗口防火墙,只需将程序添加到“允许的程序”
例如,如果您的服务运行位置是“C:\ Program Files(x86)\ MyWork \ Service1.exe”
转到防火墙,从左上角单击“允许程序或功能通过窗口防火墙”。 点击“允许其他程序” 点击“浏览”选择您的程序,例如Service1.exe 点击“添加” 它将显示在“允许程序和功能列表”下。