我如何获得的TcpListener接受多个连接,并分别与每个人的工作? [英] how do i get TcpListener to accept multiple connections and work with each one individually?

查看:208
本文介绍了我如何获得的TcpListener接受多个连接,并分别与每个人的工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个SMTP侦听器,效果很好,但只能接受一个连接。我的C#code是下面,我运行它作为一项服务。我的目标是有它runnign在服务器上,解析发送给它的多个SMTP邮件。

目前它分析了第一条消息,并停止工作。我该怎么去接受第二次,第三次,第四次...... SMTP邮件并处理它喜欢它做的第一?

这是我的code:

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用的System.Net.Sockets;
使用System.Net;
使用System.IO;

命名空间SMTP_Listener
{
    类节目
    {
        静态无效的主要(字串[] args)
        {


            的TcpListener监听器=新的TcpListener(IPAddress.Any,8000);
            TcpClient的客户端;
            的NetworkStream纳秒;

            listener.Start();

            Console.WriteLine(等待连接......);
            客户= listener.AcceptTcpClient();
            Console.WriteLine(连接接受!);

            纳秒= client.GetStream();

            使用(StreamWriter的作家=新的StreamWriter(NS))
            {
                writer.WriteLine(220本地主机SMTP服务器准备好了。);
                writer.Flush();

                使用(StreamReader的读者=新的StreamReader(NS))
                {
                    串响应= reader.ReadLine();

                    如果(response.StartsWith(HELO)及!&安培;!response.StartsWith(EHLO))
                    {
                        writer.WriteLine(500未知的命令);
                        writer.Flush();
                        ns.Close();
                        返回;
                    }

                    字符串远程= response.Replace(HELO的String.Empty).Replace(EHLO的String.Empty).Trim();

                    writer.WriteLine(250本地主机你好+遥控);
                    writer.Flush();

                    响应= reader.ReadLine();

                    如果(response.StartsWith(MAIL FROM:!))
                    {
                        writer.WriteLine(500未知的命令);
                        writer.Flush();
                        ns.Close();
                        返回;
                    }

                    远程= response.Replace(RCPT TO:,的String.Empty).Trim();
                    writer.WriteLine(250+遥控器+我喜欢这个家伙呢!);
                    writer.Flush();

                    响应= reader.ReadLine();

                    如果(!response.StartsWith(RCPT TO:))
                    {
                        writer.WriteLine(500未知的命令);
                        writer.Flush();
                        ns.Close();
                        返回;
                    }

                    远程= response.Replace(MAIL FROM:,的String.Empty).Trim();
                    writer.WriteLine(250+遥控器+我喜欢这个家伙!);
                    writer.Flush();

                    响应= reader.ReadLine();

                    如果(response.Trim()!=DATA)
                    {
                        writer.WriteLine(500未知的命令);
                        writer.Flush();
                        ns.Close();
                        返回;
                    }

                    writer.WriteLine(上独占一行354输入信息完成后,输入\\。);
                    writer.Flush();

                    INT计数器= 0;
                    StringBuilder的消息=新的StringBuilder();

                    而((响应= reader.ReadLine()。修剪())!=)。
                    {
                        message.AppendLine(响应);
                        反++;

                        如果(计数器== 1000000)
                        {
                            ns.Close();
                            返回; //真的吗?在信息1万行?
                        }
                    }

                    writer.WriteLine(250行);
                    writer.Flush();
                    ns.Close();
                    //将信息到数据库
                    Console.WriteLine(收到的消息:);
                    Console.WriteLine(message.ToString());
                }
            }

            Console.ReadKey();
        }
    }
}
 

解决方案

你可以将你的大部分code到一个单独的线程:

 静态无效的主要(字串[] args)
{
    的TcpListener监听器=新的TcpListener(IPAddress.Any,8000);
    TcpClient的客户端;
    listener.Start();

    而(真)//添加你的退出标志在这里
    {
        客户= listener.AcceptTcpClient();
        ThreadPool.QueueUserWorkItem(ThreadProc的,客户端);
    }
}
私有静态无效ThreadProc的(obj对象)
{
    VAR的客户=(TcpClient的)目标文件;
    //做你的工作在这里
}
 

I have an SMTP listener that works well but is only able to receive one connection. My C# code is below and I am running it as a service. My goal is to have it runnign on a server and parsing multiple smtp messages sent to it.

currently it parses the first message and stops working. how can I get it to accept the 2nd, 3rd, 4th... SMTP message and process it like it does the first?

here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;  

namespace SMTP_Listener
{
    class Program
    {
        static void Main(string[] args)
        {


            TcpListener listener = new TcpListener(IPAddress.Any , 8000);
            TcpClient client;
            NetworkStream ns;

            listener.Start();

            Console.WriteLine("Awaiting connection...");
            client = listener.AcceptTcpClient();
            Console.WriteLine("Connection accepted!");

            ns = client.GetStream();

            using (StreamWriter writer = new StreamWriter(ns))
            {
                writer.WriteLine("220 localhost SMTP server ready.");
                writer.Flush();

                using (StreamReader reader = new StreamReader(ns))
                {
                    string response = reader.ReadLine();

                    if (!response.StartsWith("HELO") && !response.StartsWith("EHLO"))
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    string remote = response.Replace("HELO", string.Empty).Replace("EHLO", string.Empty).Trim();

                    writer.WriteLine("250 localhost Hello " + remote);
                    writer.Flush();

                    response = reader.ReadLine();

                    if (!response.StartsWith("MAIL FROM:"))
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    remote = response.Replace("RCPT TO:", string.Empty).Trim();
                    writer.WriteLine("250 " + remote + " I like that guy too!");
                    writer.Flush();

                    response = reader.ReadLine();

                    if (!response.StartsWith("RCPT TO:"))
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    remote = response.Replace("MAIL FROM:", string.Empty).Trim();
                    writer.WriteLine("250 " + remote + " I like that guy!");
                    writer.Flush();

                    response = reader.ReadLine();

                    if (response.Trim() != "DATA")
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    writer.WriteLine("354 Enter message. When finished, enter \".\" on a line by itself");
                    writer.Flush();

                    int counter = 0;
                    StringBuilder message = new StringBuilder();

                    while ((response = reader.ReadLine().Trim()) != ".")
                    {
                        message.AppendLine(response);
                        counter++;

                        if (counter == 1000000)
                        {
                            ns.Close();
                            return;  // Seriously? 1 million lines in a message?
                        }
                    }

                    writer.WriteLine("250 OK");
                    writer.Flush();
                    ns.Close();
                    // Insert "message" into DB
                    Console.WriteLine("Received message:");
                    Console.WriteLine(message.ToString());
                }
            }

            Console.ReadKey();
        }
    }
}

解决方案

You can factor out most of your code into a separate thread:

static void Main(string[] args)
{
    TcpListener listener = new TcpListener(IPAddress.Any , 8000);
    TcpClient client;
    listener.Start();

    while (true) // Add your exit flag here
    {
        client = listener.AcceptTcpClient();
        ThreadPool.QueueUserWorkItem(ThreadProc, client);
    }
}
private static void ThreadProc(object obj)
{
    var client = (TcpClient)obj;
    // Do your work here
}

这篇关于我如何获得的TcpListener接受多个连接,并分别与每个人的工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆