![5分鐘!教你用C語言發送郵件:附送源碼+教學!](http://p2.ttnews.xyz/loading.gif)
關注《一碳科技》,獲取更多知識!
前言
相信大家都有過被C語言網絡編程所支配的恐懼吧?其實,小編在剛剛學習這方面的知識的時候也有這樣的感受,並且所有的資料都是從網絡尋找的,但是,現在你們不同了,因為這篇文章將會帶你們一步步地,寫出你們第一個使用SMTP協議來發送郵件的C語言程序,這個和小編剛學習的時候可不同呀!
文章末尾有總結,這是精髓哦
![5分鐘!教你用C語言發送郵件:附送源碼+教學!](http://p2.ttnews.xyz/loading.gif)
言歸正傳,代碼寫起來!
首先,這篇文章不是講理論的文章,而是讓你們動手實踐的文章,目的在於讓各位看官能動手寫出能編譯成功、能成功運行、能成功發送郵件的C語言程序,這篇文章不會涉及太多的理論知識,並且代碼也沒有經過特別的封裝,旨在讓各位看官能編寫出這個程序,所以看官跟著文章動手做就可以了。
第一步
首先,引用stdio.h、winsock2.h、windows.h(可有可無,下文講到),注意,這裡有一個地方有很多人會出錯,如果你要引用windows.h的話,就得在引用winsock2.h之後才能引用windows.h,否則會出現“未定義標識符”的情況,如下圖↓
這是正確寫法
錯誤寫法
按照錯誤寫法進行調試的話,會出現以下錯誤提示↓
錯誤提示
然後我們再聲明一個變量和兩個函數,變量是用來儲存服務器返回的數據的,兩個函數分別是用來創建
套接字(socket)和接收服務器返回數據的,這裡我們聲明瞭一個字符型數組,數組大小我們用BUFSIZ代替,這裡有人就會問了:“為什麼用BUFSIZ作為數組大小呢?”,答案是:“減輕系統負擔”,不理解?沒關係,先把代碼運行起來,然後再慢慢研究。除了以上步驟,我們還需要寫入以下兩行代碼,加入兩個庫文件,其中User32.lib是可有可無的,加入User32.lib只是為了能夠調用MessageBox()函數而已。
到這裡,我們的第一步完成了!接下來是第二步
第二步
初始化
前期的準備工作做好了,我們現在開始編寫我們要用到的函數——socket_connect_server(void),從字面的意思上來看,大家都應該明白這個函數是幹嘛的吧?沒錯,它是用來創建套接字並連接SMTP服務器的。
我們要創建一個套接字,初始化完成後,我們要把它記在某個地方,要不然“忘記”了怎麼辦?所以我們要聲明一個變量來存放套接字初始化後的數據——WSADATA wd,wd就是用來存放這些數據的變量。
好了,我們用到的主要變量已經聲明完畢,接下來要初始化,我們要向編譯器說明,我們要用到Ws2_32.lib 和Winsock2.h中的哪個庫文件(簡單來說就是初始化而已),如圖,代碼可以這麼寫↓
創建套接字
開始創建socket,這裡我們要用到socket()函數,socket()需要三個參數,但是一般情況下,按照圖中的代碼寫也是可以的,所以,這行代碼各位看官照抄 就行了!其實,這三個參數很容易理解,這裡就不“搬書”了。
輸入服務器信息
這裡解釋一下inet_addr()函數,它的功能是將一個點分十進制的IP轉換成一個長整數型數(u_long類型),說白了,就是數據類型轉換,將IP地址的數據類型成能夠存到addr這個結構體的數據類型。
還有一個htons()函數,它的作用是將括號裡面的數值,轉化成網絡字節順序(TCP/IP中規定數據表現形式),簡單點講,就是將括號裡面的數值轉化成另一種表現形式。
連接服務器
套接字有了,服務器也有了,接下來要幹嘛呢?那就是
連接服務器!連接服務器我們要用到connet()函數而不是bind()函數,這裡簡單的記一下“connet()用在客戶端,bind()用在服務器”。這裡跟大家說一下,connet()函數其中第一個參數是SOCKADDR類型,而我們這裡為什麼用SOCKADDR_IN類型呢?請看下圖↓
SOCKADDR_IN強制轉換成SOCKADDR類型
圖中的代碼將smtp郵箱IP地址存放在SOCKADDR_IN的S_addr成員中,然後再將端口號放在sin_port成員中,分開進行,而SOCKADDR就不一樣了,它將IP地址和端口號一起放在sa_data[14]這個成員中,這樣看來
SOCKADDR是一種通用的套接字地址,SOCKADDR_IN是internet環境下套接字的地址形式。說白了,就是“SOCKADDR_IN更適合用於網絡編程”,記住這句話就對了!第三步
就是我們的recv_show()函數,這個函數比較簡單,這裡就不多說了,照抄!
服務器已經連接了、接收數據並打印的函數也有了,接下來就是按照SMTP協議發送數據
這裡會用到send()函數,它有三個參數,分別是已連接的socket、發送的字符串、發送字符串長度、調用執行方式(一般為0)。
代碼書寫示例:send(socket_use,"發送的數據\r\n",strlen("發送的數據\r\n"),0),為什麼後面會有\r\n?這個跟SMTP協議有關,\r\n與CMD命令行發送郵件時的“回車”效果一樣。
注意:
- 發送的賬號、密碼要通過base64加密,不會如何加密?那麼,請百度搜索:“base64”
- 發送和接收的郵箱要開啟smtp服務!
- 發件人和收件人可以是同一個郵箱
- 發送郵件的最後三行語句特別重要,注意格式(文章末尾有)
接下來就是按照SMTP協議來發送數據和接收數據了
如圖,參照CMD命令通過SMTP協議發送郵件的實例,來寫C語言發送郵件的代碼↓
CMD發送郵件的過程
舉個例子,我們第一步要發送“helo 163.com”,那麼,我們用C語言發送是這樣的,send(socket_use,"helo 163.com\r\n",strlen("helo 163.com\r\n"),0),按照這行代碼,以此類推寫下去,然後再用recv_show()輸出服務器應答的信息。
注意這三行C語言代碼,跟CMD發郵件過程對比以下↓
最後
這是程序運行之後的結果
以下是全部代碼↓
圖片看不清?那就關注《一碳科技》,私信我們拿源碼哦!
閱讀更多 一碳科技 的文章