UVA 814 The Letter Carrier's Rounds

本文深入解析电子邮件应用程序中基于SMTP协议的通信流程,详述了发送方与接收方MTA间的数据交互过程,包括命令行传输及响应编码机制,强调了在成对MTA间进行邮件传递的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大致翻译:

对于电子邮件应用程序,您需要描述发生在成对mta之间的基于smtp的通信。发送方的用户代理向发送消息传输代理(MTA)提供格式化的消息。发送MTA使用SimpleMail传输协议(SMTP)与接收MTA通信。接收MTA将邮件发送到接收方的用户代理。初始化通信链路后,发送MTA将命令行(每次一行)传输到接收MTA,接收MTA在处理每个命令后返回一个三位数编码的响应。下面按每个消息的发送顺序显示这些发送命令。当同一消息发送到同一MTA的多个用户时,会有多个RCPTTO行。给不同mta的用户的消息需要单独的SMTP会话。输入输入包含mta的描述以及任意数量的消息。每个MTA的描述以MTA目的地及其名称(1到15个字母数字字符)开始。在MTA名称后面是在该MTA接收邮件的用户数量和用户列表(每个用户1到15个字母数字字符)。MTA描述以第1列中的星号结束。每条消息都以发送用户的姓名开始,然后是收件人标识符列表。每个标识符的表单是user@mtaname。消息(每行包含不超过72个字符)以第1列中的星号开始和结束。第1列中带有星号而不是发送方和接收方列表的行表示整个输入的结束。输出对于每个消息,显示发送和接收mta之间的通信。消息中提到的每个MTA都是有效的MTA;但是,目的地MTA可能不存在消息接收者。接收MTA通过使用550代码响应RCPT to命令拒绝这些用户的邮件。拒绝将不影响在同一MTA向授权用户交付。如果在特定的MTA上没有至少一个授权的收件人,则数据不会被发送。只有一个SMTP会话用于向特定MTA的用户发送消息。例如,发送给同一MTA的5个用户的消息将只有一个SMTP会话。同样,一条消息只针对同一用户一次。发送方联系接收mta的顺序与输入文件中的顺序相同。如示例输出所示,在通信前加上正在通信的MTA名称,并缩进每个非空通信行。不应打印不必要的空格。

样例输入:

MTA London 4 Fiona Paul Heather Nevil
MTA SanFrancisco 3 Mario Luigi Shariff
MTA Paris 3 Jacque Suzanne Maurice
MTA HongKong 3 Chen Jeng Hee
MTA MexicoCity 4 Conrado Estella Eva Raul
MTA Cairo 3 Hamdy Tarik Misa
*
Hamdy@Cairo Conrado@MexicoCity Shariff@SanFrancisco Lisa@MexicoCity
*
Congratulations on your efforts !!
--Hamdy
*
Fiona@London Chen@HongKong Natasha@Paris
*
Thanks for the report!  
--Fiona
*
*

样例输出:(中间没有空行,是截图的锅)

 1 #include<iostream>
 2 #include<string>
 3 #include<vector>
 4 #include<set>
 5 #include<map>
 6 using namespace std;
 7 
 8 void parse_address(const string &s,string & user,string &mta)
 9 {
10     int pos = s.find('@');//从0开始
11     user = s.substr(0, pos);//左闭右开,复制0~pos-1;
12     mta = s.substr(pos + 1);
13 }
14 int main()
15 {
16     set<string> addr;
17     string s,s2,user1,mta1,user2,mta2;
18     int n;
19     while (cin >> s&&s != "*")//MTA,第一个*
20     {
21         cin >> s >> n;
22         while (n--)
23         {
24             cin >> s2;
25             addr.insert(s2 + "@" + s);//Hamdy@Cairo这样存
26         }
27     }
28     while (cin>>s&&s!="*")//发件人收件人,数据,第五个*
29     {
30         parse_address(s, user1, mta1);//分割Hamdy@Cairo发件人
31         
32         vector<string> mta;//所有需要连接的MTA(按输入顺序)
33         map<string, vector<string> > dest;//每个MTA需要发送的用户
34         //<MTA名称,用户名列表>
35         set<string> vis;//收件人去重
36 
37         while (cin>>s2&&s2!="*")//处理收件人,第二个*
38         {
39             parse_address(s2, user2, mta2);//分割收件人
40             if (vis.count(s2))//重复的收件人  
41                 continue;
42             vis.insert(s2);
43 
44             if (!dest.count(mta2))
45             {
46                 mta.push_back(mta2);
47                 dest[mta2] = vector<string>();
48             }
49             dest[mta2].push_back(s2);
50         }
51         getline(cin, s2);//取数据前面的*的回车,第三个*
52 
53         string data;//正文数据
54         while (getline(cin, s2) && s2[0] != '*')//第四个*
55             data += "     " + s2 + "\n";
56 
57         for (int i = 0; i < mta.size(); i++)
58         {
59             string mta2;
60             mta2 = mta[i];
61             vector<string> users = dest[mta2];
62             cout << "Connection between " <<mta1 << " and " <<mta2 << endl;
63             cout << "     HELO " << mta1 << "\n";
64             cout << "     250" << endl;
65             cout <<"     MAIL FROM:<" <<s<< ">"<<endl;
66             cout << "     250" << endl;
67 
68             bool ok = false;
69             for (int j = 0; j < users.size(); j++)
70             {
71                 cout << "     RCPT TO:<" << users[j] <<">"<< endl;
72                 if (addr.count(users[j]))
73                 {
74                     ok = true;
75                     cout << "     250" << endl;
76                 }
77                 else
78                     cout << "     550" << endl;
79             }
80             if (ok)
81             {
82                 cout << "     DATA" << endl;
83                 cout << "     354" << endl;
84                 cout << data;
85                 cout << "     ."<<endl;
86                 cout << "     250" << endl;
87             }
88             cout << "     QUIT" << endl;
89             cout << "     221" << endl;
90         }
91 
92     }
93 
94     return 0;
95 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值