线程实现邮箱通信-实验报告
邮件传送协议实验报告

实验名称:邮件传送协议实验实验日期:2023年X月X日实验地点:实验室实验人员:[你的姓名]一、实验目的1. 了解邮件传送协议(SMTP)的基本原理和流程。
2. 掌握使用SMTP协议发送邮件的方法。
3. 熟悉邮件客户端的配置和使用。
二、实验原理邮件传送协议(SMTP,Simple Mail Transfer Protocol)是一种用于在互联网上传输电子邮件的协议。
SMTP协议定义了邮件客户端(如Outlook、Foxmail等)与邮件服务器之间交换邮件的规则和格式。
本实验旨在通过模拟SMTP协议的工作过程,加深对邮件传送原理的理解。
三、实验内容1. 配置邮件客户端2. 编写SMTP发送邮件的代码3. 分析SMTP协议的响应和错误信息4. 测试邮件发送功能四、实验步骤1. 配置邮件客户端(1)打开邮件客户端,如Outlook。
(2)在“文件”菜单中选择“账户设置”。
(3)点击“添加账户”,选择“电子邮件账户”。
(4)填写用户名、密码、邮箱服务器地址等信息。
(5)完成账户配置,测试邮件发送功能。
2. 编写SMTP发送邮件的代码(1)选择编程语言,如Python。
(2)导入必要的库,如smtplib和email。
(3)创建一个SMTP对象,连接到邮件服务器。
(4)创建一个邮件对象,填写发件人、收件人、主题和正文等信息。
(5)发送邮件,并捕获SMTP协议的响应和错误信息。
3. 分析SMTP协议的响应和错误信息(1)根据SMTP协议的响应代码,判断邮件发送是否成功。
(2)分析SMTP协议的错误信息,找出可能的问题原因。
(3)根据错误信息,对邮件发送代码进行修改和优化。
4. 测试邮件发送功能(1)使用配置好的邮件客户端,发送一封邮件。
(2)使用编写的SMTP发送邮件代码,发送一封邮件。
(3)比较两种方式发送邮件的结果,验证邮件发送功能。
五、实验结果与分析1. 邮件客户端配置成功,邮件发送功能正常。
2. 使用Python编写的SMTP发送邮件代码,邮件发送成功。
线程实例实验报告总结

一、实验目的本次实验旨在通过实例操作,深入了解线程的概念、创建、同步与通信机制,以及线程在实际编程中的应用。
通过实验,提高对线程的理解和运用能力,为以后开发多线程程序打下坚实基础。
二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C#三、实验内容1. 线程的基本概念线程是程序执行的最小单位,是操作系统进行资源分配和调度的基本单位。
线程具有以下特点:(1)线程是轻量级的,创建、销毁线程的开销较小。
(2)线程共享进程的资源,如内存、文件等。
(3)线程之间可以并发执行。
2. 线程的创建在C#中,可以使用以下方式创建线程:(1)使用Thread类```csharpThread thread = new Thread(new ThreadStart(MethodName));thread.Start();```(2)使用lambda表达式```csharpThread thread = new Thread(() => MethodName());thread.Start();```(3)使用匿名方法```csharpThread thread = new Thread(delegate () { MethodName(); });thread.Start();```3. 线程的同步线程同步是指多个线程在执行过程中,为了防止资源冲突而采取的协调机制。
C#提供了以下同步机制:(1)互斥锁(Mutex)```csharpMutex mutex = new Mutex();mutex.WaitOne();// 线程同步代码mutex.ReleaseMutex();```(2)信号量(Semaphore)```csharpSemaphore semaphore = new Semaphore(1, 1);semaphore.WaitOne();// 线程同步代码semaphore.Release();```(3)读写锁(ReaderWriterLock)```csharpReaderWriterLock rwlock = new ReaderWriterLock();rwlock.AcquireReaderLock();// 读取操作rwlock.ReleaseReaderLock();```4. 线程的通信线程通信是指线程之间传递消息、共享数据的过程。
邮件接收程序的设计与实现-专业实习报告

邮件接收程序的设计与实现
邮件接收程序比邮件发送程序要复杂 一些,这个程序首先需要使用MAPI消息控 件的Fetch方法读取邮件,这个过程将把用 户收件箱中所有未读邮件全部装入MAPI消 息控件中。接着,检查MAPI消息控件的 MsgCount属性以确定通过Fetch方法读取 的邮件的总数,
邮件接收程序的设计与实现
邮件接收程序的设计与实现
2:cmdNext的Click事件代码: Private Sub cmdNext_Click() If MAPIMessages1.MsgIndex < MAPIMessages1.MsgCount - 1 Then MAPIMessages1.MsgIndex = MAPIMessages1.MsgIndex + 1 /当收取信件超过1封 的时候,通过“下一封”按钮查看后面的信件 DisplayMessage Else Beep End If End Sub
邮件接收程序的设计与实现
邮件接收程序的设计与实现
代码实现过程
1:cmdPrevious的Click事件代码: Private Sub cmdPrevious() If MAPIMessages1.MsgIndex > 0 Then MAPIMessages1.MsgIndex = MAPIMessages1.MsgIndex - 1 /当收取信件超过1封 的时候,通过“上一封”按钮查看前面的信件 DisplayMessage Else Beep End If End Sub
。
3、在Form1中加入三个Label控件和一个 TextBox控件,将三个标签控件的名称属性 分别设置为“lblMsgDateReceived”、 “lblMsgOrigDisplayName”和 “IblMsgSubject”,将TextBox控件的名称 属性设置为“txtMsgNoteText”,并将标签 控件的(name)属性和文本框控件的Text 属性的内容清空。这四个控件将分别用于 显示邮件的日期、发件人、主题和内容
电子邮件客户端程序设计与实现实验报告

电子邮件客户端程序设计与实现实验报告
本次实验中,我编写一个电子邮件客户端程序,可用于发送和接收电子邮件。
该客户端程序可以支持 Simple Mail Transfer Protocol(SMTP)协议和Post Office Protocol (POP)协议,并可以连接到互联网上的邮件服务器。
首先,我采用经典的TCP/IP Socket通信库和该语言支持的SMTP/POP客户端函数,其中用于通过SMTP/POP客户端发送和接收邮件信息的核心功能函数有:协议调用,信息发送接收,文本处理和回复处理,以及异常处理等。
接着,我采用系统调用和网络函数的方式与服务器建立起连接,查找用户邮箱,读取邮件信息,发送邮件等。
最后,我利用用户界面和相应的事件处理机制,使用户能够较便捷的发送和接收邮件。
实验结果显示,编写的客户端程序可以较为便捷地连接到互联网上的邮件服务器,无论是发送邮件还是接收邮件都能较轻松地实现;并支持相应的错误处理和超时机制,使得整个电子邮件通信机制更加健全安全。
总之,本实验中,我编写了一个邮件客户端程序,可以支持SMTP/POP协议,可以连接互联网上的邮件服务器,实现电子邮件的发送和接收,该程序的执行结果也得到了较为理想的效果。
邮件服务器实训报告

邮件服务器的配置实验准备工作:1、在VM中打开2003和XP虚拟机各两台,并进行如下设置:2、在2003中安装应用程序服务器(选择SMTP服务)、电子邮件服务和DNS服务。
<SMTP组件选择时抓图><电子邮件服务选择时抓图>邮件服务器配置实训内容:总体要求:在2003上建立域的邮件服务器,新建邮箱mail01、mail02,关联Windows 账户,密码均为111。
在XP上OE添加mail01@S学号.net邮箱;在win 2003 上配置OE添加mail02@S学号.net。
这两个帐号能通过2003上的SMTP相互发送邮件,通过2003上的POP3服务接受邮件。
具体步骤:第一步、在DNS服务中添加域“S学号.net”,如“”,并添加主机记录mail指向2003服务器、再添加邮件交换记录指向。
<DNS记录抓图>第二步、在XP上使用nslookup测试域的邮件记录。
提示:set type=mx;<测试正常的抓图>第三步、在POP3服务管理工具中,新建域“”,要求设置身份验证方法为:集成Windows身份验证”。
设置磁盘配额:新用户限额100MB。
并在其中添加两个邮箱“mail01”、“mail02”并关联Windows用户,密码为111。
<域设置时的抓图><磁盘配额限制的抓图><完成后的抓图>第四步、在IIS管理器总,设置SMTP服务器常规属性-IP地址。
<完成后的抓图>********以下使用XP上的OE进行邮件服务器的测试********第五步、在XP上打开OE,添加邮件账户mail01,SMTP、POP3服务器均为2003服务器。
<邮件账户属性的服务器选项卡抓图>第六步、在windows2003上打开OE,添加邮件账户mail02,SMTP、POP3服务器均为2003服务器。
<邮件账户属性的常规选项卡抓图>第七步、在OE中分别发送以下二封邮件:●Mail01 to mail02●Mail02 to mail01查看收件箱接收情况。
计算网络邮件实验报告

一、实验目的1. 理解电子邮件的工作原理;2. 掌握电子邮件系统的基本架构;3. 学习使用电子邮件客户端发送和接收邮件;4. 了解电子邮件安全性和隐私保护措施。
二、实验环境1. 操作系统:Windows 102. 浏览器:Chrome3. 邮件客户端:Outlook4. 邮件服务器:Gmail三、实验内容1. 邮件系统的基本架构2. 电子邮件客户端的使用3. 邮件发送与接收4. 邮件安全性与隐私保护四、实验步骤1. 邮件系统的基本架构(1)了解电子邮件的工作原理:电子邮件系统采用SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)进行邮件的发送和接收。
用户通过邮件客户端(如Outlook、Foxmail等)向邮件服务器发送邮件,邮件服务器将邮件存储在收件人的邮箱中,收件人通过邮件客户端接收邮件。
(2)学习电子邮件系统的基本架构:电子邮件系统主要由以下几个部分组成:1. 用户:使用邮件客户端发送和接收邮件;2. 邮件客户端:负责发送和接收邮件;3. 邮件服务器:负责存储和管理邮件;4. SMTP服务器:负责邮件的发送和传输;5. POP3/IMAP服务器:负责邮件的接收。
2. 电子邮件客户端的使用(1)安装邮件客户端:以Outlook为例,下载并安装Outlook软件。
(2)配置邮件客户端:打开Outlook,进入“文件”菜单,选择“添加账户”,然后按照提示填写邮件服务提供商(如Gmail)、用户名、密码等信息。
3. 邮件发送与接收(1)撰写邮件:在Outlook中,点击“新建邮件”按钮,填写收件人地址、主题和正文,然后点击“发送”。
(2)接收邮件:Outlook会自动检查邮箱,并将新收到的邮件显示在收件箱中。
4. 邮件安全性与隐私保护(1)使用SSL加密:在配置邮件客户端时,选择使用SSL加密连接,以保护邮件传输过程中的安全性。
(2)设置垃圾邮件过滤:在Outlook中,可以设置垃圾邮件过滤规则,避免接收垃圾邮件。
Java实现多线程邮件发送

Java实现多线程邮件发送 利⽤java多线程技术配合线程池实现多任务邮件发送.1.基本邮件发送MailSenderpackage hk.buttonwood.ops.email;import java.io.File;import java.util.Date;import java.util.Enumeration;import java.util.Properties;import java.util.Vector;import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.Address;import javax.mail.AuthenticationFailedException;import javax.mail.BodyPart;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/*** 简单邮件(带附件的邮件)发送器*/public class MailSender {private Logger logger = LoggerFactory.getLogger(MailSender.class);public static void main(String[] args) {// 这个类主要是设置邮件MailSenderInfo mailInfo = new MailSenderInfo();mailInfo.setMailServerHost("");mailInfo.setMailServerPort("25");mailInfo.setValidate(true);mailInfo.setUserName("151********");mailInfo.setPassword("myb1991517");// 您的邮箱密码mailInfo.setFromAddress("151********@");mailInfo.setToAddress("930147677@");mailInfo.setSubject("windowfg");mailInfo.setContent("asgjhkhl");// 这个类主要来发送邮件MailSender sms = new MailSender();Vector<File> files = new Vector<File>();files.addElement(new File("/home/maybo/myProject/2015-11-04/mt_2015-11-04_2.pdf"));mailInfo.setFile(files);sms.sendWithAttachment(mailInfo);// 发送⽂体格式// sms.sendHtmlMail(mailInfo);//发送html格式}/*** 发送邮件*/public MailState sendWithAttachment(MailSenderInfo info) {MailState mailState=new MailState();mailState.setDate(info.getDate());mailState.setState(MailState.SUCCESS);mailState.setDesc("邮箱发送成功!");mailState.setAddress(info.getToAddress());Session session = null;Properties props = System.getProperties();props.put("mail.smtp.host", info.getMailServerHost());if (info.isValidate()) { // 服务器需要⾝份认证props.put("mail.smtp.auth", "true");MyAuthenticator smtpAuth = new MyAuthenticator(info.getUserName(), info.getPassword());session = Session.getDefaultInstance(props, smtpAuth);} else {props.put("mail.smtp.auth", "false");session = Session.getDefaultInstance(props, null);}//session.setDebug(true);Transport trans = null;try {Address from_address = new InternetAddress(info.getFromAddress(), info.getUserName()); msg.setFrom(from_address);} catch (java.io.UnsupportedEncodingException e) {//e.printStackTrace();mailState.setState(MailState.ERROR);String message = "邮件发送失败!";mailState.setDesc(message);}InternetAddress[] address = { new InternetAddress(info.getToAddress()) };msg.setRecipients(Message.RecipientType.TO, address);msg.setSubject(info.getSubject());Multipart mp = new MimeMultipart();MimeBodyPart mbp = new MimeBodyPart();mbp.setContent(info.getContent().toString(), "text/html;charset=gb2312");mp.addBodyPart(mbp);if (!info.getFile().isEmpty()) {// 有附件Enumeration<?> efile = info.getFile().elements();while (efile.hasMoreElements()) {mbp = new MimeBodyPart();String filename = efile.nextElement().toString(); // 选择出每⼀个附件名FileDataSource fds = new FileDataSource(filename); // 得到数据源mbp.setDataHandler(new DataHandler(fds)); // 得到附件本⾝并⾄⼊BodyPartmbp.setFileName(fds.getName()); // 得到⽂件名同样⾄⼊BodyPartmp.addBodyPart(mbp);}info.getFile().removeAllElements();}msg.setContent(mp); // Multipart加⼊到信件msg.setSentDate(new Date()); // 设置信件头的发送⽇期// 发送信件msg.saveChanges();trans = session.getTransport("smtp");trans.connect(info.getMailServerHost(), info.getUserName(), info.getPassword());trans.sendMessage(msg, msg.getAllRecipients());trans.close();} catch (AuthenticationFailedException e) {mailState.setState(MailState.ERROR);String message = "邮件发送失败!错误原因:\n" + "⾝份验证错误!";mailState.setDesc(message);// e.printStackTrace();} catch (MessagingException e) {//e.printStackTrace();String message = "邮件发送失败!错误原因:" + e.getMessage();mailState.setDesc(message);mailState.setState(MailState.ERROR);}return mailState;}/*** 以⽂本格式发送邮件** @param mailInfo* 待发送的邮件的信息*/public boolean sendTextMail(MailSenderInfo mailInfo) {// 判断是否需要⾝份认证MyAuthenticator authenticator = null;Properties pro = mailInfo.getProperties();if (mailInfo.isValidate()) {// 如果需要⾝份认证,则创建⼀个密码验证器authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());}// 根据邮件会话属性和密码验证器构造⼀个发送邮件的sessionSession sendMailSession = Session.getDefaultInstance(pro, authenticator);try {// 根据session创建⼀个邮件消息Message mailMessage = new MimeMessage(sendMailSession);// 创建邮件发送者地址Address from = new InternetAddress(mailInfo.getFromAddress());// 设置邮件消息的发送者mailMessage.setFrom(from);// 创建邮件的接收者地址,并设置到邮件消息中Address to = new InternetAddress(mailInfo.getToAddress());mailMessage.setRecipient(Message.RecipientType.TO, to);// 设置邮件消息的主题mailMessage.setSubject(mailInfo.getSubject());// 设置邮件消息发送的时间mailMessage.setSentDate(new Date());// 设置邮件消息的主要内容String mailContent = mailInfo.getContent();mailMessage.setText(mailContent);Transport.send(mailMessage);return true;} catch (MessagingException ex) {ex.printStackTrace();}return false;}/*** 以HTML格式发送邮件** @param mailInfo* 待发送的邮件信息*/public static boolean sendHtmlMail(MailSenderInfo mailInfo) {// 判断是否需要⾝份认证MyAuthenticator authenticator = null;Properties pro = mailInfo.getProperties();// 如果需要⾝份认证,则创建⼀个密码验证器if (mailInfo.isValidate()) {authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); }// 根据邮件会话属性和密码验证器构造⼀个发送邮件的sessionSession sendMailSession = Session.getDefaultInstance(pro, authenticator);try {// 根据session创建⼀个邮件消息Message mailMessage = new MimeMessage(sendMailSession);// 创建邮件发送者地址Address from = new InternetAddress(mailInfo.getFromAddress());// 设置邮件消息的发送者mailMessage.setFrom(from);// 创建邮件的接收者地址,并设置到邮件消息中Address to = new InternetAddress(mailInfo.getToAddress());// Message.RecipientType.TO属性表⽰接收者的类型为TOmailMessage.setRecipient(Message.RecipientType.TO, to);// 设置邮件消息的主题mailMessage.setSubject(mailInfo.getSubject());// 设置邮件消息发送的时间mailMessage.setSentDate(new Date());// MiniMultipart类是⼀个容器类,包含MimeBodyPart类型的对象Multipart mainPart = new MimeMultipart();// 创建⼀个包含HTML内容的MimeBodyPartBodyPart html = new MimeBodyPart();// 设置HTML内容html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");mainPart.addBodyPart(html);// 将MiniMultipart对象设置为邮件内容mailMessage.setContent(mainPart);// 发送邮件Transport.send(mailMessage);return true;} catch (MessagingException ex) {ex.printStackTrace();}return false;}}2.邮件发送信息MailSenderInfopackage hk.buttonwood.ops.email;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.Arrays;import java.util.Properties;import java.util.Vector;public class MailSenderInfo implements Serializable {// 发送邮件的服务器的IP和端⼝private String mailServerHost;private String mailServerPort = "25";private long uid;//唯⼀标⽰// 邮件发送者的地址private String fromAddress;// 邮件接收者的地址private String toAddress;// 登陆邮件发送服务器的⽤户名和密码private String userName;private String password;// 是否需要⾝份验证private boolean validate = false;private String filename="";private Vector file = new Vector(); //⽤于保存发送附件的⽂件名的集合 private String subject;// 邮件的⽂本内容private String content;// 邮件附件的⽂件名private String[] attachFileNames;//邮箱来源private int portfolio;//邮箱来源⽇期private String date;public void setUid(long uid) {this.uid = uid;}public long getUid() {return uid;}public void setDate(String date) {this.date = date;}public void setPortfolio(int portfolio) {this.portfolio = portfolio;}public String getDate() {return this.date;}public int getPortfolio() {return this.portfolio;}/*** 获得邮件会话属性*/public Properties getProperties(){Properties p = new Properties();p.put("mail.smtp.host", this.mailServerHost);p.put("mail.smtp.port", this.mailServerPort);p.put("mail.smtp.auth", validate ? "true" : "false");return p;}public String getMailServerHost() {return mailServerHost;}public void setFile(Vector file) {this.file = file;}public Vector getFile() {return this.file;}public void setFilename(String filename) {this.filename = filename;}public String getFilename() {return this.filename;}public void setMailServerHost(String mailServerHost) {this.mailServerHost = mailServerHost;}public String getMailServerPort() {return mailServerPort;}public void setMailServerPort(String mailServerPort) {this.mailServerPort = mailServerPort;}public boolean isValidate() {return validate;}public void setValidate(boolean validate) {this.validate = validate;}public String[] getAttachFileNames() {return attachFileNames;}public void setAttachFileNames(String[] fileNames) {this.attachFileNames = fileNames;}public String getFromAddress() {return fromAddress;}public void setFromAddress(String fromAddress) {this.fromAddress = fromAddress;}public String getPassword() {return password;public void setPassword(String password) {this.password = password;}public String getToAddress() {return toAddress;}public void setToAddress(String toAddress) {this.toAddress = toAddress;}public String getUserName() {return userName;}public void setUserName(String userName) {erName = userName;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getContent() {return content;}public void setContent(String textContent) {this.content = textContent;}public Object deepCopy() throws Exception{// 将该对象序列化成流,因为写在流⾥的是对象的⼀个拷贝,⽽原对象仍然存在于JVM⾥⾯。
电子邮件的使用实训报告

一、实训背景随着信息技术的飞速发展,电子邮件已经成为人们日常生活和工作中不可或缺的通讯工具。
为了提高我的信息技术应用能力,更好地适应社会发展的需求,我参加了本次电子邮件使用实训。
本次实训旨在通过实际操作,掌握电子邮件的基本功能和使用技巧,提高电子邮件的写作和发送效率。
二、实训内容1. 电子邮件的基本功能(1)注册邮箱账号首先,我选择了国内知名的邮箱服务商——网易邮箱,注册了一个个人邮箱账号。
在注册过程中,我按照提示填写了基本信息,并设置了密码和邮箱昵称。
(2)登录邮箱注册成功后,我使用账号和密码登录邮箱,进入邮箱主界面。
主界面分为收件箱、发件箱、草稿箱、垃圾箱等模块,方便用户管理邮件。
(3)撰写邮件在发件箱中,我点击“写邮件”按钮,进入撰写邮件界面。
在此界面,我可以填写收件人、主题、正文等内容。
同时,还可以添加附件、设置邮件格式等。
(4)发送邮件完成邮件撰写后,点击“发送”按钮,邮件即可成功发送。
在发送过程中,我了解到邮件发送速度与网络环境、邮件大小等因素有关。
2. 电子邮件的使用技巧(1)提高邮件发送速度在撰写邮件时,尽量简洁明了,避免冗长的内容。
此外,合理设置邮件大小,不超过邮箱服务商的限制,可以加快邮件发送速度。
(2)提高邮件阅读体验在撰写邮件时,注意使用分段、加粗、斜体等格式,使邮件内容更易于阅读。
同时,合理使用图片、链接等元素,增强邮件的吸引力。
(3)防止邮件被误删定期清理邮箱,将重要的邮件归类保存。
同时,为重要邮件设置“标记”或“加星”等标记,以便于查找。
(4)提高邮件安全性在设置邮箱密码时,使用复杂且不易被破解的密码。
此外,开启邮箱的“登录保护”功能,防止他人非法登录。
三、实训收获通过本次电子邮件使用实训,我收获颇丰:1. 掌握了电子邮件的基本功能和使用技巧,提高了自己的信息技术应用能力。
2. 了解了电子邮件在日常生活和工作中的重要作用,为今后的学习和工作打下了坚实基础。
3. 认识到电子邮件的安全性至关重要,学会了如何保护自己的邮箱账户。
进程通信-用共享内存和PV操作实现邮箱通信

本实验中邮箱的pv操作 信号量: Aavail=3 ,Afull=0 ,Bavail=3 , Bfull=0; A发送端进程s1: A尝试发送数据 P(Bavail) A 向 B 发送数 据,写入共享 发送成功 V(Bfull) Goto s1 B接收端进程s2: B尝试接收数据 P(Bfulll) B 从共享中读取 数据 接收成功 V(Bavail) Goto s2n semun{ • int val; • struct semid_ds *buf; • unsigned short *array; • }; • int setsemvalue(int id,int x){ • union semun s; • s.val=x; • if(semctl(id,0,SETVAL,s)==-1) return 0; • else return 1; • }
设计方案
采用两个程序并行的方式,打开两个 终端,为两个进程都创建一个邮箱。 并且,要求先输入操作命令,使信箱 执行哪种操作,以完成两个进程间的 邮件通信。 同时,还应采用pv操作,使当邮箱满 和空的时候,分别不能执行发送和接 收的工作。
关键代码的分析
• • • • • • • • • • • • • • • • union semun{ int val; struct semid_ds *buf; unsigned short *array; }; int creatsem(int i,int w){ int value; if(w) value = semget((key_t)i,1,0667|IPC_CREAT); else value=semget((key_t)i,1,0666|IPC_CREAT); if(value==-1) { printf("semget error"); return 0;
线程通讯实验报告

一、实验目的1. 理解线程通讯的基本概念和机制。
2. 掌握常用的线程通讯方法,如管道、信号量、消息队列等。
3. 通过实验,加深对线程同步和互斥的理解。
4. 提高编程能力,掌握多线程编程技术。
二、实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 开发环境:GCC编译器三、实验内容本次实验主要涉及以下内容:1. 管道(Pipe)通讯2. 命名管道(Named Pipe)通讯3. 信号量(Semaphore)通讯4. 消息队列(Message Queue)通讯5. 共享内存(Shared Memory)通讯6. 套接字(Socket)通讯四、实验步骤及结果分析1. 管道(Pipe)通讯实验步骤:- 创建两个进程,父进程和子进程。
- 父进程向管道写入数据。
- 子进程从管道读取数据。
实验结果:- 父进程成功向管道写入数据。
- 子进程成功从管道读取数据。
结论:管道是一种半双工的通信方式,适用于具有亲缘关系的进程间的通信。
2. 命名管道(Named Pipe)通讯实验步骤:- 创建两个无亲缘关系的进程,进程A和进程B。
- 进程A向命名管道写入数据。
- 进程B从命名管道读取数据。
实验结果:- 进程A成功向命名管道写入数据。
- 进程B成功从命名管道读取数据。
结论:命名管道是一种半双工的通信方式,适用于无亲缘关系的进程间的通信。
3. 信号量(Semaphore)通讯实验步骤:- 创建两个线程,线程A和线程B。
- 线程A和线程B使用信号量实现同步。
实验结果:- 线程A和线程B成功实现同步。
结论:信号量是一种常用的线程同步机制,可以防止多个线程同时访问共享资源。
4. 消息队列(Message Queue)通讯实验步骤:- 创建两个线程,线程A和线程B。
- 线程A向消息队列发送消息。
- 线程B从消息队列接收消息。
实验结果:- 线程A成功向消息队列发送消息。
- 线程B成功从消息队列接收消息。
结论:消息队列是一种高效的线程间通信方式,可以克服信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
邮件服务配置实验报告

一、实验目的1. 熟悉电子邮件服务的基本概念和组成;2. 掌握电子邮件服务器的配置方法;3. 了解邮件传输协议及其工作原理;4. 学会使用邮件客户端发送和接收邮件。
二、实验环境1. 操作系统:Windows 102. 邮件服务器:Sendmail3. 邮件客户端:Microsoft Outlook4. 邮件传输协议:SMTP、POP3、IMAP三、实验步骤1. 安装Sendmail邮件服务器(1)下载Sendmail软件包;(2)安装Sendmail软件包;(3)启动Sendmail服务。
2. 配置Sendmail邮件服务器(1)编辑sendmail.mc文件,配置邮件服务器的基本信息,如域名、主机名等;(2)使用m4命令将sendmail.mc文件编译成sendmail.cf文件;(3)配置sendmail.cf文件,设置SMTP、POP3、IMAP服务器的端口和认证方式;(4)配置主机别名和域名,设置邮件服务器接收和发送的域名;(5)配置访问控制,设置允许或拒绝特定主机访问邮件服务器。
3. 配置邮件客户端(1)打开Microsoft Outlook,选择“文件”→“信息”→“添加账户”;(2)选择“手动配置服务器设置或特殊服务器类型”,点击“下一步”;(3)选择“Internet帐户”,点击“下一步”;(4)在“电子邮件地址”中输入您的邮箱地址,在“用户名”中输入邮箱账号,在“密码”中输入邮箱密码;(5)选择“POP3”作为接收邮件服务器类型,输入SMTP服务器地址(通常是您的邮箱域名),在“接收邮件服务器”和“发送邮件服务器”中输入SMTP服务器地址;(6)配置POP3服务器的端口为110,配置SMTP服务器的端口为25;(7)点击“测试账户设置”,确保一切正常。
4. 发送和接收邮件(1)在Outlook中,点击“创建新邮件”,填写收件人、主题和邮件内容;(2)点击“发送”按钮,将邮件发送到收件人的邮箱;(3)在Outlook中,点击“接收邮件”,从收件人的邮箱接收邮件。
计算机网路原理实验报告(邮件客户端)

Experiment Report of Computer Network’s Theory——Email Client(JAVA)Designer’s Name:Guidance Counselors:Profession:Student ID:ContentExperiment Purpose 2Experiment RequestingDesign Ideas and ThoughtCode DescriptionOperation Effect and ResultResult Explanation 19Improvable Part 20Experiment Conclusion 201.E xperiment Purpose1)Establish a series of Graphic Interface2)Login the system have just been created successfully 3)Choose recipient, subject and content4)Send the email just been written directly and ensure the recipient can really receive the right email directly 5)Can use any programming language to achieve our goals6)Above all, the protocol must be SMTP2.E xperiment Requesting1)We should install SDK at first, we can follow the guidance given by 《Instruction of Experiment》.2)Run the code we have edited and see the result only when we just have some compile platform for java.3)We must set up a series of Graphic Interface——first, we should have an interface to login the email clientsuch as requiring username and password; next, weneed an interface to write our personal email and havethe bars which allow us input the recipient address,email subject and the content and so on.4)Follow 3), we should ensure the email can really be sent to the recipient mailbox including that the emailmust be right. To check and test our system is successor not, we should login the recipient mailbox and findout whether we can receive the email or not.3.D esign Idea and ThoughtWe might send or receive email every day, and really know the operation about these so that we can follow the our cognitive habits and the knowledge we have just acquired from the lessons and 《Instruction of Experiment》to design our own email client with personallycharacteristics.At this experiment, we use java language and eclipse software to achieve our goals, which as same as the last experiment.In the first place, we should edit code to establish two Graphic interfaces as follow:1)The first interface should allow us to input us (that is the username and password of Sender. At thisexperiment, we choose the 163 mailbox).2)After we login the mailbox, we should take the next action——input the recipient address, emailsubject and content in the other interface whichshould be establish after the first interface.After we have set up general framework for user, we face some difficulties now which we must solve.1)How can we get the information that user input in the two interface such as recipient address oremail content and so on?2)When we have gathered all the information about the sender, recipient and the email itself,how can we collect these information into amessage3)While we own such a message, how can we send this message to the right recipient? (e.g. All themailbox appeared on the internet now have thefunction of Authentication, how can we pass thecheckout? Or else, anyone can pretend to be usand send many junk mails.Only when we solve these problems above, can we really establish emailclient with fully functions.On the next part, we will show how we solve these problems by explaining the code we have edited!4.C ode Description1)LoginPage.javaAt this class, we have just established the first Graphic Interface, which allow us input the username and password of sender.import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.*;publicclass LoginPage implements ActionListener{JFrame jfmain;JPanel jp1,jp2,jp3;JLabel title,t1,t2;JTextField jt1;JPasswordField jt2;JButton jbon;public LoginPage(){jfmain=new JFrame("制作人:刘耀蓬(10283012)");jfmain.setBounds(500, 240, 350, 200);JPanel jp1=new JPanel();title=new JLabel("用户登陆界面");title.setHorizontalAlignment(SwingConstants.CENTER);title.setFont(new Font("华文宋体",30,30));jp1.add(title);jfmain.add(jp1,BorderLayout.NORTH);jp2=new JPanel();jt1=new JTextField("",25);jt2=new JPasswordField("",25);t1=new JLabel("用户:");t2=new JLabel("密码:");SpringLayoutjla=new SpringLayout();jp2.setLayout(jla);jp2.add(t1);jp2.add(jt1);jp2.add(t2);jp2.add(jt2);jla.putConstraint(SpringLayout.WEST,t1, 5, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,t1, 1, SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,jt1, 45, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,jt1, 1, SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,t2, 5, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,t2, 35, SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,jt2, 45, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,jt2, 34,SpringLayout.NORTH, jp2);jfmain.add(jp2,BorderLayout.CENTER);jp3=new JPanel();jbon=new JButton("登录");jbon.addActionListener(this);jp3.add(jbon,BorderLayout.NORTH);jfmain.add(jp3,BorderLayout.SOUTH);jfmain.setVisible(true);jfmain.setDefaultCloseOperation(jfmain.EXIT_ON_CLOSE);}At the pervious codes used for established the graphic framework, at the next part we will show the results.publicvoid actionPerformed(ActionEvent e){if(e.getSource()==jbon){String S=new String(jt2.getPassword());SendMailPagesm=new SendMailPage(jt1.getText(),S);jfmain.setVisible(false);}}}There is an important part we must state:“SendMailPagesm=new SendMailPage(jt1.getText(),S);”The sentence allow a new object named sm acquired two inlet parameters——jt1.getText() includes the username of sender and the S includes the password of sender. These two parameters will be passed to the next Graphic Interface.2)SendMailPage.javaAt this class, we have just established the second Graphic Interface, which allow us input the recipient address, email subject and the content.import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.*;publicclass SendMailPage implements ActionListener {JFrame jfmain;JPanel jp1,jp2,jp3;JLabel title,t1,t2,t3;JTextField jt1,jt2;JTextArea jtext;JButton jbon;String username,password;SendMailPage(String u,String p){username=u;password=p;jfmain=new JFrame("制作人:刘耀蓬(10283012)");jfmain.setBounds(430, 200, 500, 400);jp1=new JPanel();title=new JLabel("邮箱客户端书写界面");title.setFont(new Font("华文宋体",30,30));jp1.add(title);jp2=new JPanel();jt1=new JTextField("",35);jt2=new JTextField("",35);t1=new JLabel("收信件方:");t2=new JLabel("邮件主题:");t3=new JLabel("邮件内容:");jtext=new JTextArea();jtext.setLineWrap(true);jtext.setFont(new Font("华文宋体",15,15));jtext.setSize(475,200);SpringLayoutjla=new SpringLayout();jp2.setLayout(jla);jp2.add(t1);jp2.add(jt1);jp2.add(t2);jp2.add(jt2);jp2.add(t3);jp2.add(jtext);jla.putConstraint(SpringLayout.WEST,t1, 5, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,t1, 10, SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,jt1, 75, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,jt1, 10,SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,t2, 5, SpringLayout.WEST,jp2);jla.putConstraint(SpringLayout.NORTH,t2, 55, SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,jt2, 75, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,jt2, 54,SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,t3, 5, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,t3, 95, SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.WEST,jtext, 5, SpringLayout.WEST, jp2);jla.putConstraint(SpringLayout.NORTH,jtext, 115,SpringLayout.NORTH, jp2);jla.putConstraint(SpringLayout.SOUTH,jtext, 0,SpringLayout.SOUTH, jp2);jbon=new JButton("发送");jbon.addActionListener(this);jp3=new JPanel();jp3.add(jbon,BorderLayout.CENTER);jfmain.add(jp1,BorderLayout.NORTH);jfmain.add(jp2,BorderLayout.CENTER);jfmain.add(jp3,BorderLayout.SOUTH);jfmain.setVisible(true);jfmain.setDefaultCloseOperation(jfmain.EXIT_ON_CLOSE);}At the pervious codes used for established the graphic framework, at the next part we will show the results.publicvoid actionPerformed(ActionEvent e){if(e.getSource()==jbon){EventQueue.invokeLater(new Runnable() {publicvoid run() {try {// System.out.println(t1.getText());SMTPClientframe0 = newSMTPClient(username,password,jt1.getText(),jt2.getText(),jtext.getTex t());} catch (Exception e) {e.printStackTrace();}}});}}}“SMTPClient frame0 = newSMTPClient(username,password,jt1.getText(),jt2.getText(),jtex t.getText());”——this sentence allows a new object frame0 acquired five inlet parameters: The username includes the username of sender, the password includes the password of sender, the jt1.getText() includes the recipient address, thejt2.getText() includes the email subject and the jtext.getText() includes the email content.All the parameters will be passed to the Main function!3)MailMessage.javaAt this class, we have just defined the pattern of the Message we collected from all the information which user inputted in the two Graphic Interfaces.publicclass MailMessage {private String from; //发送方private String to; //接收方private String datafrom; //邮件内显示:发送人private String datato; //邮件内显示:接收人private String subject; //主题private String content; //内容private String date; //时间private String user; //发送方用户名private String password; //发送方密码public String getPassword() {return password;}publicvoid setPassword(String password) { this.password = password;}public String getUser() {return user;}publicvoid setUser(String user) {er = user;}public String getContent() {return content;}publicvoid setContent(String content) { this.content = content;}public String getDatafrom() {return datafrom;}publicvoid setDatafrom(String datafrom) { this.datafrom = datafrom;}public String getDatato() {return datato;}publicvoid setDatato(String datato) { this.datato = datato;}public String getDate() {return date;}publicvoid setDate(String date) {this.date = date;}public String getFrom() {return from;}publicvoid setFrom(String from) {this.from = from;}public String getSubject() {return subject;}publicvoid setSubject(String subject) {this.subject = subject;}public String getTo() {return to;}publicvoid setTo(String to) {this.to = to;}}4)SMTPClient.javaimport java.awt.BorderLayout;import java.awt.EventQueue;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import .Socket;import .UnknownHostException;import java.util.StringTokenizer;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.border.EmptyBorder;import sun.misc.BASE64Encoder;publicclass SMTPClient extends JFrame {privateboolean debug=true;private JPanel contentPane;BASE64Encoder encode=new BASE64Encoder(); //用于加密后发送用户名和密码BASE64Encoder is an encryption algorithm provided by Local Library Function. If you have the interest about this encryption algorithm, you can “baidu” it.publicstaticvoid main(String[] args) throws UnknownHostException, IOException {LoginPagelp=new LoginPage();}In fact, The process of the calls to classes is “LoginPage——SendMailPage——SMTPClient——MailMessage”public SMTPClient(String u,Stringp,Stringr,Stringt,String c)throws UnknownHostException, IOException {MailMessage message=new MailMessage();message.setFrom(u);//发件人message.setTo(r);//收件人String server="";//邮件服务器message.setSubject(t);//邮件主题message.setContent(c);//邮件内容message.setDatafrom(u);//发件人,在邮件的发件人栏目中显示message.setDatato(r);//收件人,在邮件的收件人栏目中显示message.setUser(u);//登陆邮箱的用户名message.setPassword(p);//登陆邮箱的密码We can see that all the parameters (information) come from the inlet parameters of ConstructorsSMTPClientsmtp=new SMTPClient(server,25);boolean flag;flag=smtp.sendMail(message,server);if(flag){JOptionPane.showMessageDialog(this,"邮件发送成功!");}else{JOptionPane.showMessageDialog(this,"邮件发送失败!");}}Despite the mail sending is success or not, we will prompt a dialog box to tell user.private Socket socket;public SMTPClient(String server,int port) throws UnknownHostException, IOException{socket=new Socket(server,25);}Socket Number is 25 (SMTP)privateint sendServer(String str,BufferedReaderin,BufferedWriter out) throws IOException{out.write(str);out.newLine();out.flush();return getResult(in);}publicint getResult(BufferedReader in) throws IOException{String line="";line=in.readLine();//从服务器返回消息中读出状态码,将其转换成整数返回StringTokenizerst=new StringTokenizer(line," ");return Integer.parseInt(st.nextToken());}//邮件体publicvoid data(Stringfrom,Stringto,Stringsubject,Stringcontent,BufferedReaderin,BufferedWr iter out) throws IOException{int result;result=sendServer("DATA",in,out);out.write("From: "+from);out.newLine();out.write("To: "+to);out.newLine();out.write("Subject: "+subject);out.newLine();out.newLine();out.write(content);out.newLine();//句号加回车结束邮件内容输入result=sendServer(".",in,out);}The Above sentences are based on the format of Message with the SMTP protocols.//发送邮件主程序publicboolean sendMail(MailMessagemessage,String server){try{BufferedReaderin=new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriterout=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()) );getResult(in);sendServer("HELO "+server,in,out);sendServer("AUTH LOGIN",in,out);//连接服务器sendServer(encode.encode(message.getUser().getBytes()),in,out);//用户名sendServer(encode.encode(message.getPassword().getBytes()),in,out); //密码sendServer("MAIL FROM:<"+message.getFrom()+">",in,out);//发件箱sendServer("RCPT TO:<"+message.getTo()+">",in,out);//收件箱In general, we sent the information to the server () and required be passed through the Authentication and can match the email format.data(message.getDatafrom(),message.getDatato(),message.getSubject(),m essage.getContent(),in,out);//DATA数据+内容sendServer("QUIT",in,out);}catch(Exception e){e.printStackTrace();returnfalse;}returntrue;}}5.O peration Effects and Results1)Run the code at firstNow, there is a new Graphic Interface appeared in front of us!2)Input username and password of senderNow, we login successfully, and there is a new Graphic Interface appeared in front of us!3)Input recipient address, email subject and content4)Send the email5)Check our email6.R esults ExplanationAs far as we can see, our email client with SMTP protocol is successful!We follow the steps given by the previous pictures, the username and password used for testing is we registered before long at 163 mailbox homepage.We use the same user as the sender and recipient because that is convenient to test. However, we can also use different user even use different SMTP server!7.I mportable PartHowever, things need to be completed.As all we know, there is an apparent defect is that we cannot ensure input the registered username and password, which means we can alsoinput username and password at will even such user do not exist. Of course, such an email cannot be sent successfully, but the sender cannot know about it.In general, we need the function that check out the username and password, we also need a function that can tell us if recipient really received the email instead send successfully or not.8.E xperiment ConclusionWe really should be glad to meet the opportunity to operate and conductthe experiment at first. We must realized that practices is also important as theory.From this experiment, we do acquire a deeper understanding about SMTP Protocols and learned a lot about how to explain, describe and show the process of email sending and receiving. And we also strengthen our skill of programming either in fact especially in the area of Graphic Interface Programming.Generally speaking, we really meet the requesting and implement all the function we need, at last, we catch the goals!。
E-mail实验报告

实验报告专业: 网络工程 班级:10网络(1)班 学号: 姓名课程名称: 网络操作系统课程设计 学年:2012-2013 学期:1 / 2 课程类别:专业必修 限选 任选 实践 实验时间: 2012年11月9日实验名称:电子邮件服务的基本配置 实验目的和要求:了解电子邮件服务的基本配置,在Linux 环境下能独立配置电子邮件服务器,进行邮件传送功能。
实验软硬件条件:硬件: Intel E3200 2.40GHz CPU1GB 内存 软件: Microsoft Windows XPVMware Workstation ACE 版(Fedora Linux 2.6.x kernel.vmx )实验内容:1、配置sendmail 服务;2、配置dovecot 服务;3、创建邮件用户组;4、分别在windows 和linux 环境下实现邮件传送;实验结果:见附页小结:这次实验,了解到了电子邮件服务的基本配置,能够通过注重相关细节找出错误,反复实验后,实验成功。
评定成绩: 批阅教师: 年 月 日√ √实验步骤:一、安装Sendmail服务器实验前提,打开VMware Workstation开启Fedora Linux,操作系统必须安装了DNS服务器。
安装DNS服务器,在图形界面“主菜单”中选择“系统设置”——“添加删除应用程序”,找到“Sendmail服务器”进行安装。
检查sendmial安装的版本检查sendmail是否运行二、网络配置选择“系统”——“网络”,打开“网络配置”窗口,双击打开“以太网设备”窗口,设置IP 地址“192.168.1.20”,子网掩码“255.255.255.0”默认网关“192.168.1.0”DNS选项:主机名:主DNS:192.168.1.20单击“确定”,在“网络配置”窗口点击“激活”按钮,连接网络。
三、Sendmail服务器的配置1.Sendmail服务器的配置文件有/etc/mail/access、/etc/mail/aliases、/etc/mail/local-host-names等,根据试验要求,对配置文件进行参数的配置。
线程mailbox机制

线程mailbox机制
线程mailbox机制是一种线程间通信和数据传输的媒介,类似于FIFO(先进先出)队列。
这种机制在多个线程之间做数据通信或内部数据缓存时非常有用。
在mailbox机制中,数据可以通过一个线程发送到mailbox,然后由另一个线程从mailbox中获取。
这种机制可以确保数据的顺序性和一致性,避免了多线程之间的数据竞争和线程间的锁竞争。
在mailbox机制的实现中,通常会包含一些关键组件,如cpipe类和signaler类。
cpipe类负责存储、读写发送给mailbox的命令,通过其内部的变量实现了支持一个读线程和一个写线程同时在管道上进行读写操作而不会引起并发问题。
signaler类则负责在命令写入到cpipe之后,通过调用send()接口给读线程发送信号,读线程调用signaler 类的recv()函数及wait()函数执行接收信号的操作。
此外,mailbox机制还可以与其他线程通信机制如事件(event)和旗语(semaphore)结合使用,以实现更复杂的线程同步和数据传输需求。
总的来说,线程mailbox机制是一种高效的线程间通信和数据传输方式,可以提高多线程程序的性能和可靠性。
实现内部exchange邮件服务器和外部exchange邮件服务器邮件通信的实验报告

实验时间
实验人
实验名称
实现邮件的外部收发;创建和管理SMTP连接器
所属模块及课程
benet-S2B-管理和维护企业邮件系统第四章课后实验
实验目的
掌握实现邮件外部收发和SMTP连接器的创建、管理方法。源自实验拓扑无实验步骤
一、实现邮件的外部收发
1.创建DNS区域和MX记录:
在外部DNS上创建正向查找区域,如下:(
设置出站安全:
设置出站连接:
配置外部DNS地址:
3.进行域之间的邮件发送验证:
从
发送:
确认接收:
从
发送:
确认接收:
实验任务一完成
二、创建和管理SMTP连接器
1.创建SMTP连接器:
在常规选项卡中进行如下设置,并添加本地桥头服务器:
在地址空间选项卡中添加连接器的电子邮件域:
2.管理SMTP连接器:
设置邮件传递选项:
同样创建
在新建的正想查询区域中新建主机记录,并创建邮件交换记录:
新建
在
运行CMD,使用nslookup进行如下测试:
测试结果正确
2.配置SMTP虚拟服务器的入站设置:
在exchange系统管理器中对SMTP虚拟服务器设置访问限制:
确认虚拟服务器的相关信息:
设置身份验证:
设置中继信息:
配置SMTP虚拟服务器的出站设置:
可对其日程安排设置:
设置“传递限制”选项:
添加收件人:
3.登陆邮箱用户进行验证:
在
确认收到:
在
确认接收:
试验完成
实验总结
通过实验掌握了在不同域之间实现exchange邮件传输的方法,能熟练的对MX记录和SMTP连接器进行设置和管理。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
进程通信实验报告一、实验名称:进程通信二、实验目的:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。
三、实验原理:邮箱机制类似于日常使用的信箱。
对于用户而言使用起来比较方便,用户只需使用send ()向对方邮箱发邮件 receive ()从自己邮箱取邮件, send ()和 receive ()的内部操作用户无需关心。
因为邮箱在内存中实现,其空间有大小限制。
其实send ()和 receive ()的内部实现主要还是要解决生产者与消费者问题。
四、实验内容:进程通信的邮箱方式由操作系统提供形如send ()和receive ()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上。
在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。
五、背景知识介绍:1、sembuf 数据结构struct sembuf{unsigned short int sem_num; //semaphore numbershort int sem_op; //semaphore operationshort int sem_flg; //operation flag};sem_num :操作信号在信号集中的编号,第一个信号的编号是0。
进程A 进程B 信箱A 信箱B Send()Send() receive() receive()sem_op:如果其值为正数,该值会加到现有的信号内含值中。
通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。
通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
sem_flg:信号操作标志,可能的选择有两种IPC_NOWAIT //对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
IPC_UNDO //程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。
这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。
2、 semop函数函数原型:int semop(int semid, struct sembuf *sops, unsigned nsops);参数说明:semid:信号集的识别码,可通过semget获取。
sops:指向存储信号操作结构的数组指针。
nsops:信号操作结构的数量,恒大于或等于1。
返回说明:成功执行时,两个系统调用都返回0。
失败返回-1,错误信息保存在errno中。
3、semget函数函数原型:int semget(key_t key,int nsems,int semflg);参数说明:key:关键字值一般是由系统调用ftok()返回的nsems:指出了一个新的信号量集中应该创建的信号量的个数semflg:打开和存取操作与参数semflg中的内容相关。
返回说明:如果成功,则返回信号量集的IPC标识符。
如果失败,返回-1,错误信息保存在errno中。
4、semctl函数函数原型:int semctl(int semid,int semnum,int cmd,union semun arg);参数说明:senid:关键字值semnum:信号量数目cmd:要操作的具体命令arg:semnu的一个联合类型的副本。
返回说明:返回值:如果成功,则为一个正数。
如果失败,则为-1。
错误信息保存在errno 中。
5、pthread_create函数函数原型:int pthread_create(pthread_t *restrict tidp,const pthread_attr_t*restrict attr,void*(*start_rtn)(void*),void *restrict arg);参数说明:tidp:指向线程标识符的指针。
attr:用来设置线程属性。
第三个参数是线程运行函数的起始地址。
arg:运行函数的参数。
六、设计方案:1、定义两个数组当作两个邮箱int a_buf[5],b_buf[5];邮箱的容量为5。
2、定义两个指针指向邮箱的顶部int a_buf_top=0,b_buf_top=0;初始时邮箱都为空3、定义semaphore_P和semaphore_V两个函数实现P.V原语操作,用P.V原语实现进程的互斥。
4、定义发送和接收信息的函数,其中void * A_Send(void *arg)为A发送信息,void * B_Send(void *arg)为B发送信息,void *A_Receive(void *arg)为A接收信息;void*B_Receive(void *arg)为B接收信息。
5、调用创建线程函数,让上述四个函数并行运行。
七、预计的实验结果:A_Receive()和 B_Receive()分别接收B_Send()和 A_Send()发出的信息,发送的信息和接受的信息应该一样。
八、关键代码的分析:/***************************************** P原语操作* *************************************/int semaphore_P(int sem_id){struct sembuf p;p.sem_num=0;p.sem_op=-1;p.sem_flg=SEM_UNDO;if(semop(sem_id,&p,1)==-1){printf(errno);return 0;}return 1;}/**************************************** V原语操作* **********************************/int semaphore_V(int sem_id){struct sembuf v;v.sem_num=0;v.sem_op=1;v.sem_flg=SEM_UNDO;if(semop(sem_id,&v,1)==-1){printf(errno);return 0;}return 1;}/**************************************** A向B发送信息* ************************************/void * A_Send(void *arg){int i;for(i=0;i<10;i++){semaphore_P(sem_idAs); //P操作semaphore_P(a_mutex_semaphore); //互斥int number=rand(); //随机数为发送的邮件printf("A send to B:%d\n",number);b_buf[b_buf_top]=number;//邮箱B中接收A发送的邮件b_buf_top+=1;//A向B发送邮件,B的邮件数量加一semaphore_V(a_mutex_semaphore); //互斥semaphore_V(sem_idBr);//V操作sleep(1);}}九、调试记录:于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a, 所以在使用pthread_create创建线程时,在编译中要加-lpthread参数 gcc -w -lpthread semaphore.c十、实际的实验结果:ada@ada-desktop:~/OS$ gcc -w -o semaphore -lpthread semaphore.cada@ada-desktop:~/OS$ ./semaphoreB send to A:123A receive from B:123A send to B:222B receive from A: 222B send to A:111A receive from B:111A send to B:12334B receive from A: 12334ada@ada-desktop:~/OS$十一、实验结果分析:四个线程并发运行, A_Send()和 B_Send()发出信息,同时打印出发出的信息内容;A_Receive()和 B_Receive()分别接收B_Send()和 A_Send()发出的信息,并打印出接受的信息内容。
发出的内容和接收的内容一样,符合时间情况。
十二、附代码#include<unistd.h>#include<stdlib.h>#include<stdio.h>#include<pthread.h>#include<semaphore.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include<errno.h>int a_buf[5],b_buf[5]; //邮箱的容量为5int a_buf_top=0,b_buf_top=0;//假设初始时邮箱都为空int sem_idAs,sem_idBs; //例如sem_idAs代表A此时最多可以向B发送的邮件数int sem_idAr,sem_idBr; //例如sem_idAr代表A此时邮箱中受到的邮件数int a_mutex_semaphore,b_mutex_semaphore; //互斥信号量/***************************************** P原语操作* *************************************/int semaphore_P(int sem_id)struct sembuf p;p.sem_num=0;p.sem_op=-1;p.sem_flg=SEM_UNDO;if(semop(sem_id,&p,1)==-1){printf(errno);return 0;}return 1;}/**************************************** V原语操作* **********************************/int semaphore_V(int sem_id){struct sembuf v;v.sem_num=0;v.sem_op=1;v.sem_flg=SEM_UNDO;if(semop(sem_id,&v,1)==-1){printf(errno);return 0;}return 1;}/**************************************** A向B发送信息* ************************************/void * A_Send(void *arg){int i;for(i=0;i<10;i++){semaphore_P(sem_idAs); //P操作semaphore_P(a_mutex_semaphore); //互斥int number=rand(); //随机数为发送的邮件printf("A send to B:%d\n",number);b_buf[*b_top] = num++;//邮箱B中接收A发送的邮件,(*b_top)+=1;//A向B发送邮件,B的邮件数量加一semaphore_V(a_mutex_semaphore); //互斥semaphore_V(sem_idBr);//V操作sleep(1);}}/***************************************** A接收B的信息* ***************************************/void *A_Receive(void *arg){int i;for( i=0;i<10;i++ ){semaphore_P(sem_idAr);//P操作semaphore_P(b_mutex_semaphore);//互斥a_buf_top-=1;//A接收B发送邮件,A的邮件数量减一printf("A receive from B:%d\n",a_buf[a_buf_top]);semaphore_V(b_mutex_semaphore); //互斥semaphore_V(sem_idBs);//V操作sleep(1);}}/**************************************** B向A发送信息* ************************************/void *B_Send(void *arg){int i;for(i=0;i<10;i++){semaphore_P(sem_idBs);semaphore_P(b_mutex_semaphore);int number=rand();printf("B send to A:%d\n",number);a_buf[a_buf_top]=number;a_buf_top+=1;semaphore_V(b_mutex_semaphore);semaphore_V(sem_idAr);sleep(1);}}/***************************************** B接收A的信息* ***************************************/void *B_Receive(void *arg){int i;for( i=0;i<10;i++){semaphore_P(sem_idBr);semaphore_P(a_mutex_semaphore);b_buf_top-=1;printf("B receive from A: %d\n",b_buf[b_buf_top]);semaphore_V(a_mutex_semaphore);semaphore_V(sem_idAs);sleep(1);}}int main(){/*创建线程1*/pthread_t thread1;pthread_t thread2;pthread_t thread3;pthread_t thread4;/*创建信号量*/if( (sem_idAs=semget( (key_t)1,1,IPC_CREAT|0660) )==-1 ) return 1;if( (sem_idBs=semget( (key_t)2,1,IPC_CREAT|0660) )==-1 ) return 1;if( (sem_idAr=semget( (key_t)3,1,IPC_CREAT|0660) )==-1 ) return 1;if( (sem_idBr=semget( (key_t)4,1,IPC_CREAT|0660) )==-1 ) return 1;if( (a_mutex_semaphore=semget( (key_t)5,1,IPC_CREAT|0660) )==-1 ) return 1;if( (b_mutex_semaphore=semget( (key_t)6,1,IPC_CREAT|0660) )==-1 ) return 1;/*控制信号队列的运作*/semctl(sem_idAs,0,SETVAL,0);semctl(sem_idBs,0,SETVAL,0);semctl(sem_idAr,0,SETVAL,0);semctl(sem_idBr,0,SETVAL,0);semctl(a_mutex_semaphore,0,SETVAL,1);semctl(b_mutex_semaphore,0,SETVAL,1);//调用四个线程,让四个函数并行运行pthread_create(&thread1, NULL, A_Send, NULL);pthread_create(&thread2, NULL, B_Send, NULL);pthread_create(&thread3, NULL, A_Receive, NULL);pthread_create(&thread4, NULL, B_Receive, NULL);sleep(60);//保证主程序退出之前邮箱操作已经完成return 0;}。