java发送邮件、接收邮件

news2024/11/14 2:44:11

邮件协议

SMTP

SMTP (Simple Mail Transfer Protocol),即简单邮件传输协议

默认端口是25,通过SSL协议加密之后的默认端口是465

用户必须首先设置 SMTP 服务器,然后才能配置电子邮件客户端与其连接。完成此操作后,用户按下电子邮件上的“发送”按钮,并在客户端和服务器之间建立 SMTP 连接以允许发送电子邮件。SMTP 连接建立在传输控制协议 (TCP)连接之上。

SMTP发件服务器,如smtp.163.com、smtp.qq.com


POP3

POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本。

默认端口是110,通过SSL协议加密之后的默认端口是995

POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,但是对邮件的操作并不会反馈到邮箱服务器上。

POP3收件服务器,如pop.163.com、pop.qq.com


IMAP

IMAP (Internet Mail Access Protocol),即交互式邮件存取协议,是一个应用层协议,

默认端口是143,通过SSL协议加密之后的默认端口是993

开启了IMAP后,您在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。

IMAP收件服务器,如imap.163.com、imap.qq.com


邮箱授权码

现在邮箱大多为邮箱客户端设置了独立密码或授权码(即通过Smtp方式发送邮件密码处不是填邮箱登录密码,而是要填授权码)

以163邮箱为例,开通过程如下:

进去后,点击开启。开启完成后状态变为”已开启“


java 发邮件

JavaMail

JavaMail是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。

JavaMail提供的是一些标准的邮件管理接口,有如下几个核心组件。

  • javax.mail.Session:表示整个邮件的会话,所有的类都要通过session才可用。
  • javax.mail.Message:Message类表示的是邮件传递的内容。
  • javax.mail.Address:当确定好Session和Message之后,就可以通过Address进行发送地址的指定。
  • javax.mail.Authenticator:使用此类可以通过用户名和密码保护资源。
  • javax.mail.Transport:在消息发送的最后一步使用此类,此类的功能是使用指定的语言发送消息。
  • javax.mail.Store:此类主要是进行信息的读、写等操作,也可以通过此类读取文件夹中的邮件。
  • javax.mail.Folder:用于对邮件进行分级管理。

虽然JavaMail是Sun的API之一,但它还没有被加在标准的java开发工具包中(Java Development Kit),使用JavaMail进行邮件的开发,因此如果需要使用的话你需要首先从Oracle官网上下载JavaMail的开发包。

我们可以在pom文件中引入如下依赖

<dependency> 
   <groupId>javax.mail</groupId> 
   <artifactId>mail</artifactId> 
   <version>1.4.7</version> 
</dependency> 

由于我使用commons-email做邮件发送,而且它会自动引入javax.mail依赖,就不单独引入了


commons-email

commons-email它构建在Java Mail API 之上,主要是为了简化它。

pom文件依赖

    <dependency>
         <groupId>org.apache.commons</groupId>
          <artifactId>commons-email</artifactId>
          <version>1.5</version>
    </dependency>

Commons-Email的核心是Email类,它是一个抽象类,提供了发送邮件的核心功能。具体有以下几个实现类

  • SimpleEmail:发送简单邮件,即纯文本邮件
  • MultiPartEmail:发送带附件的邮件
  • HtmlEmail:发送超文本邮件
  • ImageHtmlEmail:发送图文混排的超文本邮件

HtmlEmail
HtmlEmail类通常用来发送html格式的邮件,他也支持邮件携带普通文本、附件和内嵌图片。
ImageHtmlEmail
ImageHtmlEmail类通常是用来发送Html格式并内嵌图片的邮件,它拥有所有HtmlEmail的功能,但是图片主要是以html内嵌的为主。

下面开始,是使用Commons Email发送邮件的举例


SimpleEmail

SimpleEmail:发送简单邮件,即纯文本邮件

 public static void main(String[] args) throws EmailException {
     Email email = new SimpleEmail();
     //设置邮箱服务器,这里我使用的163邮箱
     email.setHostName("smtp.163.com");
     //填写邮件服务器端口:465和25选填
     email.setSmtpPort(465);
     //开启debug日志
     //email.setDebug(true);
     //设置用户名(邮箱)和授权码(授权码是用于登录第三方邮件客户端的专用密码)
     //邮箱开启授权只需要登陆邮件,在里边设置一下就行了.
     email.setAuthenticator(new DefaultAuthenticator("your_email@163.com", "your_auth_password"));
     //开启ssl连接
     email.setSSLOnConnect(true);
     //填写发送者的邮箱
     email.setFrom("your_email@163.com");
     //填写发送日期
     email.setSentDate(new Date());
     //填写邮件标题
     email.setSubject("TestMail-1月20号");
     //邮件内容
     email.setMsg("This is a test mail ... :-)");
     //填写接收者的邮箱,我是发给了自己的qq邮箱
     email.addTo("target_email_address@qq.com");
     //发送
     email.send();
 }

执行结果:


MultiPartEmail

MultiPartEmail类通常用来发送流媒体类型的邮件,允许附件和文本类型数据一起发送。

public static void main(String[] args) throws EmailException {
    MultiPartEmail email = new MultiPartEmail();
    //设置邮箱服务器,在这里我使用的163邮箱
    email.setHostName("smtp.163.com");
    //填写邮件服务器端口:465和25选填
    email.setSmtpPort(465);
    //开启debug日志
    //email.setDebug(true);
    //设置用户名(邮箱)和授权码(授权码是用于登录第三方邮件客户端的专用密码)
    //邮箱开启授权只需要登陆邮件,在里边设置一下就行了.
    email.setAuthenticator(new DefaultAuthenticator("your_email@163.com", "your_auth_password"));
    //开启ssl连接
    email.setSSLOnConnect(true);
    //填写发送者的邮箱
    email.setFrom("your_email@163.com");
    //填写发送日期
    email.setSentDate(new Date());
    //填写邮件标题
    email.setSubject("TestMail-Attachment-1月20号");
    //邮件内容
    email.setMsg("我的附件发给你了.");
    //填写接收者的邮箱,我是发给了自己的qq邮箱
    email.addTo("target_email_address@qq.com");
    //email.addCc("抄送人邮箱");
    // 添加附件
    EmailAttachment attachment = new EmailAttachment();
    //填写附件位置
    attachment.setPath("C:\\Users\\Administrator\\Desktop\\问题收集.txt");
    attachment.setDisposition(EmailAttachment.ATTACHMENT);
    //填写附件描述
    attachment.setDescription("附件描述");
    //填写附件名称,要与上面一致填写路径中的附件名称一致,要不然收到附件的时候会有问题
    attachment.setName("问题收集.txt");
    email.attach(attachment);
    //发送
    email.send();
}

执行结果:


java接收邮件

POP3接收邮件

接收邮件常用的协议有pop3,imap和exchange。exchange是微软的邮箱协议,Jakarta Mail暂不支持。

JavaMail API中定义了一个java.mail.Store类,应用程序调用这个类的方法就可以获得用户邮箱中的各个邮件夹的信息。

javaMail中的使用Folder对象表示邮件夹,通过Folder对象的方法应用程序进而又可以获得该邮件夹中的所有邮件信息。

而每封邮件信息JavaMail又分别使用了一个Message对象进行封装

用于返回指定名称的邮件夹(Folder)对象

 Folder folder = store.getFolder("inbox");
  1. 通过POP3协议获得的Store对象调用这个方法时,邮件夹名称只能指定为"INBOX"。
public class StoreMail {
 final static String USER = "robot"; // 用户名
 final static String PASSWORD = "password520"; // 密码
 public final static String MAIL_SERVER_HOST = "mail.***.com"; // 邮箱服务器
 public final static String TYPE_HTML = "text/html;charset=UTF-8"; // 文本内容类型
 public final static String MAIL_FROM = "[email protected]"; // 发件人
 public final static String MAIL_TO = "[email protected]"; // 收件人
 public final static String MAIL_CC = "[email protected]"; // 抄送人
 public final static String MAIL_BCC = "[email protected]"; // 密送人
 public static void main(String[] args) throws Exception {
  // 创建一个有具体连接信息的Properties对象
  Properties prop = new Properties();
  prop.setProperty("mail.debug", "true");
  prop.setProperty("mail.store.protocol", "pop3");
  prop.setProperty("mail.pop3.host", MAIL_SERVER_HOST);
  // 1、创建session
  Session session = Session.getInstance(prop);
  // 2、通过session得到Store对象
  Store store = session.getStore();
  // 3、连上邮件服务器
  store.connect(MAIL_SERVER_HOST, USER, PASSWORD);
  // 4、获得邮箱内的邮件夹
  Folder folder = store.getFolder("INBOX");
  folder.open(Folder.READ_ONLY);
  // 获得邮件夹Folder内的所有邮件Message对象
  Message[] messages = folder.getMessages();
  for (int i = 0; i < messages.length; i++) {
   String subject = messages[i].getSubject();
   String from = (messages[i].getFrom()[0]).toString();
   System.out.println("第 " + (i + 1) + "封邮件的主题:" + subject);
   System.out.println("第 " + (i + 1) + "封邮件的发件人地址:" + from);
  }
  // 5、关闭
  folder.close(false);
  store.close();
 }
}
  1. //由于POP3协议无法获知邮件的状态,所以getUnreadMessageCount()得到的是收件箱的邮件总数

  2. System.out.println("未读邮件数:" + folder.getUnreadMessageCount());

文件夹上的getPermanentFlags方法返回一个Flags对象,该对象包含该文件夹实现支持的所有标志。

mail.pop3.host

Flags.Flag.SEEN

邮件阅读标记,标识邮件是否已被阅读。


IMAP接收邮件

同样需要先开启授权码

public final static String MAIL_SERVER_HOST = "imap.163.com"; // 邮箱服务器

public static void main(String[] args) throws Exception {
    // 创建一个有具体连接信息的Properties对象
    Properties prop = new Properties();
      prop.setProperty("mail.debug", "true");
    //指定接收的邮件协议
    prop.setProperty("mail.store.protocol", "imap");
    prop.setProperty("mail.imap.host", MAIL_SERVER_HOST);
    prop.setProperty("mail.imap.port", "143");
    // 1、创建session
    Session session = Session.getInstance(prop);
    // 2、通过session得到Store对象
    Store store = session.getStore("imaps");
    // 3、连上邮件服务器
    store.connect(MAIL_SERVER_HOST, USER, PASSWORD);
    // 4、获得邮箱内的邮件夹 POP协议的话,这里只能是INBOX
    Folder folder = store.getFolder("INBOX");
    System.out.println("INBOX exist:" + folder.exists());
    //
    Folder defaultFolder = store.getDefaultFolder();
    Folder[] folders = defaultFolder.list("*");
    for (Folder folder1 : folders) {
        IMAPFolder imapFolder = (IMAPFolder) folder1;
        //javamail中使用id命令校验chekOpened,去掉
        imapFolder.doCommand(new IMAPFolder.ProtocolCommand() {
            @Override
            public Object doCommand(IMAPProtocol p) throws ProtocolException {
                p.id("FUTONG");
                return null;
            }
        });
    }
    //以只读方式打开收件箱
    folder.open(Folder.READ_ONLY);
    System.out.println("邮件总数:" + folder.getMessageCount());
    //由于POP3协议无法获知邮件的状态,所以getUnreadMessageCount()得到的是收件箱的邮件总数
    System.out.println("未读邮件数:" + folder.getUnreadMessageCount());
    //由于POP3协议无法获知邮件的状态,所以下面得到的结果始终都是为0
    System.out.println("删除邮件数:" + folder.getDeletedMessageCount());
    System.out.println("新邮件数:" + folder.getNewMessageCount());
    // 获得邮件夹Folder内的所有邮件Message对象
    Message[] messages = folder.getMessages();
    for (int i = 0; i < messages.length; i++) {
        String subject = messages[i].getSubject();
        String from = (messages[i].getFrom()[0]).toString();
        System.out.println("第 " + (i + 1) + "封邮件的主题:" + subject);
        System.out.println("第 " + (i + 1) + "封邮件的发件人地址:" + from);
        System.out.println("第 " + (i + 1) + "读写标识:" + messages[i].getFlags().contains(Flags.Flag.SEEN));
    }
    // 5、关闭
    folder.close(false);
    store.close();
}

1


附件下载

// 获得邮件夹Folder内的所有邮件Message对象
Message[] messages = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
    String subject = messages[i].getSubject();
    String from = (messages[i].getFrom()[0]).toString();
    System.out.println("第 " + (i + 1) + "封邮件的主题:" + subject);
    System.out.println("第 " + (i + 1) + "封邮件的发件人地址:" + from);
    System.out.println("第 " + (i + 1) + "读写标识:" + messages[i].getFlags().contains(Flags.Flag.SEEN));
    Part mp = (Part) messages[i];
    boolean containAttach = isContainAttach(mp);
    if (containAttach) {
        //包含附件,进行附件下载
        System.out.println("第 " + (i + 1) + "封邮件,包含附件");
        saveAttachMent(mp, "C:\\Users\\Administrator\\Desktop\\Attach");
    }
}

这个不一定是static方法,我是为了在main方法里测试,才这么写的

    /**
     *  * 判断此邮件是否包含附件
     *
     * @throws MessagingException
     */
    public static boolean isContainAttach(Part part) throws Exception {
        boolean attachflag = false;
        String contentType = part.getContentType();
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            // 获取附件名称可能包含多个附件
            for (int j = 0; j < mp.getCount(); j++) {
                BodyPart mpart = mp.getBodyPart(j);
                String disposition = mpart.getDescription();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    attachflag = true;
                } else if (mpart.isMimeType("multipart/*")) {
                    attachflag = isContainAttach((Part) mpart);
                } else {
                    String contype = mpart.getContentType();
                    if (contype.toLowerCase().indexOf("application") != -1)
                        attachflag = true;
                    if (contype.toLowerCase().indexOf("name") != -1)
                        attachflag = true;
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachflag = isContainAttach((Part) part.getContent());
        }
        return attachflag;
    }


    /**
     *  * 【保存附件】
     *
     * @throws Exception
     * @throws IOException
     * @throws MessagingException
     * @throws Exception
     */
    public static void saveAttachMent(Part part, String saveAttachPath) throws Exception {
        String fileName = "";
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int j = 0; j < mp.getCount(); j++) {
                BodyPart mpart = mp.getBodyPart(j);
                String disposition = mpart.getDescription();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    fileName = mpart.getFileName();
                    if (fileName.toLowerCase().indexOf("GBK") != -1) {
                        fileName = MimeUtility.decodeText(fileName);
                    }
                    saveFile(fileName, mpart.getInputStream(), saveAttachPath);
                } else if (mpart.isMimeType("multipart/*")) {
                    fileName = mpart.getFileName();
                } else {
                    fileName = mpart.getFileName();
                    if ((fileName != null)) {
                        fileName = MimeUtility.decodeText(fileName);
                        saveFile(fileName, mpart.getInputStream(), saveAttachPath);
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            saveAttachMent((Part) part.getContent(), saveAttachPath);
        }
    }

    /**
     *  * 【真正的保存附件到指定目录里】
     */
    private static void saveFile(String fileName, InputStream in, String storedir) throws Exception {
        String osName = System.getProperty("os.name");
        String separator = "";
        if (osName == null)
            osName = "";
        if (osName.toLowerCase().indexOf("win") != -1) {
            // 如果是window 操作系统
            separator = "/";
            if (storedir == null || storedir.equals(""))
                storedir = "c:\tmp";
        } else {
            // 如果是其他的系统
            separator = "/";
            storedir = "/tmp";
        }
        File strorefile = new File(storedir + separator + fileName);
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(strorefile));
            bis = new BufferedInputStream(in);
            int c;
            while ((c = bis.read()) != -1) {
                bos.write(c);
                bos.flush();
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            bos.close();
            bis.close();
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1397933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv5改进 | 主干篇 | 华为移动端模型GhostnetV2一种移动端的专用特征提取网络

一、本文介绍 本文给大家带来的改进机制是华为移动端模型Ghostnetv2,华为GhostNetV2是为移动应用设计的轻量级卷积神经网络(CNN),旨在提供更快的推理速度,其引入了一种硬件友好的注意力机制,称为DFC注意力。这个注意力机制是基于全连接层构建的,它的设计目的是在通用硬…

【Qt】对象树与坐标系

需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 一、Qt Creator快捷键 二、对象树 1、对象树的析构 2、自定义类的编写…

K8S--安装Nginx

原文网址&#xff1a;K8S--安装Nginx-CSDN博客 简介 本文介绍K8S安装Nginx的方法。 1.创建Nginx目录及配置文件 mkdir -p /work/devops/k8s/app/nginx/{config,html} 在config目录下创建nginx.conf配置文件&#xff0c;内容如下&#xff1a; # events必须要有 events {wo…

TestCaseAssiant使用说明

目录 说明 工具界面 功能描述 Xmind转测试用例 测试组件 测试用例 用例优先级 用例前提 用例操作步骤 用例期望结果 Excel测试用例转Testlink xml 用例模板 使用技巧: TestLink Xml转Excel测试用例 说明 本文为小编之前博文中介绍的工具使用说明 Xmind转Excel测…

市场复盘总结 20240119

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 昨日主题投资 连板进级率 11/39 28.2% 二进三&#xff1a; 进级率低 43% 最常用的二种方法&#xff1a; 方…

使用emby在Nas群晖搭建一个私人影院

1、安装Emby 打开套件中心搜索emby并安装 2、新增一个共享文件夹 设置好&#xff0c;无脑下一步到应用 给emby赋予这个文件夹的读写权限 保存 3、打开emby service 选择媒体库

SDL2 连续帧图像显示

QT使用SDL多窗口显示视频&#xff08;linux&#xff0c;ubuntu&#xff09;_linux qt sdl-CSDN博客 QT使用SDL播放YUV视频 - C - QT SDL调用OPENGL渲染图像 - C - 心得 C 使用SDL显示RGB图像数据_c sdl-CSDN博客 SDL库入门&#xff1a;掌握跨平台游戏开发和多媒体编程_sdl开…

SpringBoot 3.1.7 集成 SpringCloud OpenFeign

一、环境准备 准备一个项目&#xff0c;项目中有3个模块&#xff0c;1 1. FeignClient&#xff08;下图的goods-center&#xff09; 2. FeignApi(下图的user-api) &#xff0c;这个模块为其他2个模块的公共依赖模块&#xff0c;相当于2个项目通信的协议 3. FeignServer (下…

基于 UniAPP 社区论坛项目多端开发实战

社区论坛项目多端开发实战 基于 UniAPP 社区论坛项目多端开发实战一、项目准备1.1 ThinkSNS 简介及相关文档1.2 使用 UniAPP 构建项目1.3 构建项目文件结构1.4 配置页面 TabBar 导航1.5 使用 npm 引入 uView UI 插件库 二、首页功能实现2.1 首页 header 广告位轮播图功能实现2.…

旅游项目day07

目的地攻略展示 根据目的地和主题查询攻略 攻略条件查询 攻略排行分析 推荐排行榜&#xff1a;点赞数收藏数 取前十名 热门排行榜&#xff1a;评论数浏览数 取前十名 浏览数跟评论数差距过大&#xff0c;可设置不同权重&#xff0c;例如&#xff1a;将浏览数权重设置为0.3…

Visual Studio中,每次新建文件都会自动出现提前设置好的头文件配置方法

主要是修改 newcfile.cpp 文件&#xff0c;可以用everything或者Listary等软件直接搜索文件&#xff0c;直接跳到第4步 1.图标右击——>打开文件所在位置 2.到达IDE地址后在当前目录下找VC文件夹 3.再找 VCProjectItems 文件夹——newcfile.cpp文件 4.用记事本打开&#xff…

阿里云ECS使用docker搭建mysql服务

目录 1.确保正确安装好docker 2.安装mysql镜像 3.创建容器&#xff08;设置端口映射、目录映射&#xff09; 1.确保正确安装好docker 安装教程&#xff1a; 阿里云ECS(CentOS镜像)安装docker-CSDN博客https://blog.csdn.net/qq_62262918/article/details/135686614?spm10…

基于Redisson的RAtomicLong实现全局唯一工单号生成器

最近几年&#xff0c;我一直从事的是运营平台业务开发。每天&#xff0c;我们都需要处理大量的工单配置工作。为了生成工单号&#xff0c;我们建立了一张专用的数据库表&#xff0c;用于记录和生成工单号。每次创建工单时&#xff0c;我们会查询这张表&#xff0c;根据年份字段…

Adobe XD 55.2.12.2软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; Adobe XD 55.2.12.2是一款专业级的图形界面UI/UX设计工具&#xff0c;拥有丰富的功能和强大的性能。它集成了原型设计、界面设计和交互设计等多种功能…

深入理解Rust基本类型

文章目录 一、概述二、数值类型2.1、整数类型2.2、浮点类型2.3、数字运算2.4、位运算2.5、序列&#xff08;Range&#xff09;2.6、有理数和复数 三、字符、布尔、单元类型3.1、字符类型3.2、布尔类型&#xff08;bool&#xff09;3.3、单元类型 团队博客: 汽车电子社区 一、概…

【SpringCloud】微服务框架后端部署详细过程记录20240119

前言&#xff1a;前两天公司接到客户提供的一个微服务框架&#xff0c;导师让我在本地部署验证一下该框架的可用性&#xff0c;借此机会记录一下微服务项目的一个基本部署流程&#xff0c;仅供学习参考&#xff0c;如有不足还请指正&#xff01; 文件结构 提供的压缩文件共包含…

pytorch GPU版本安装 python windows

annanconda环境 创建虚拟环境 pytorch19_gpu create -n pytorch19_gpu python3.9 激活环境 conda activate pytorch19_gpu 查找CUDA版本是12.0&#xff0c;查找方式&#xff0c;win r输入cmd进入命令行模式&#xff0c;输入nvidia-smi&#xff0c;如下&#xff0c; 查找如…

《向量数据库指南》——为什么说向量数据库是更适合AI体质的“硬盘”

其“AI原生”的体质,具体表现在几个方面: 1.更高的效率。 AI算法,要从图像、音频和文本等海量的非结构化数据中学习,提取出以向量为表示形式的“特征”,以便模型能够理解和处理。因此,向量数据库比传统基于索引的数据库有明显优势。 2.更低的成本。 大模型要从一种新…

基于Django的Python应用—学习笔记—功能完善

一、让用户可以输入信息 创建forms.py 创建基于表单的页面的方法几乎与前面创建网页一样&#xff1a;定义一个 URL &#xff0c;编写一个视图函数并编写一个模板。一个主要差别是&#xff0c;需要导入包含表单 的模块forms.py 。 from django import forms from .models impor…

【C语言】linux内核ipoib模块 - ipoib_intf_init

一、ipoib_intf_init函数定义 int ipoib_intf_init(struct ib_device *hca, u8 port, const char *name,struct net_device *dev, struct ipoib_dev_priv *priv) {struct rdma_netdev *rn netdev_priv(dev);int rc;priv->ca hca;priv->port port;rc rdma_init_netde…