標籤彙整: C

C語言中的localtime被多次使用引發的思考

  今天寫某個程式時,出現一個奇妙的問題,輸出的時間戳總是不正確,查了半天百思不得其解。我把出問題的代碼簡化成下面的形式:

輸出結果是:
debug1::20160818
debug2::20160729
debug3::20160729

  debug2和debug3的位置本想分別輸出目前的時間now和前推的時間las,而結果並沒有符合預想。看了看代碼,在前一次debug1輸出now,和後一次debug2輸出now之間,並沒有對結構體now做任何賦值操作,而now的內容卻改變成了和las一樣的。
  這個問題讓我百思不得其解,怎麼看我都沒有對now進行操作,唯一的解釋就是now和las指針指向的是同一個地址。最後不斷的測試縮小範圍,把問題鎖定到localtime()上。於是上網查詢了一下localtime()的文檔,發現localtime()不僅不是線程安全的函數,不建議使用,而且只能同時使用一次,因為localtime()不是可重入的。
  所以說我的now和las確實指向了同一個地址,因為我是在Linux下編譯的所以並沒有提示,如果在VS下編譯就會看見localtime()不是線程安全函數的提示。於是我從網上找到了libc提供的另一個函數localtime_r(),修改程序如下:

輸出結果是:
debug1::20160818
debug2::20160818
debug3::20160729

  於是問題解決了,還有要注意的是,Windows下並沒有localtime_r,與其相同的函數是localtime_s。

======
kujou_rin

C語言socket編程發送HTTP請求實例

前幾天在自己的私服中用c寫了一個模擬股市系統,所使用的數據是通過socket發送HTTP請求,然後獲得新浪財經的接口頁面進行處理。那麼現在我們把需求和需要做的事情總結一下:
1、如何發送HTTP請求
2、請求到某個股票網站的輸入和輸出分別是什麼
3、處理收到的字符串數據

先試著寫一個簡單的HTTP請求發送和接收程序

上面的例子使用非阻塞的recv作為接收,優點是接收後不會阻塞的運行程序進行接下來的輸出打印,而缺點是如果返回的頁面數據很多,分包之後會發現recv接收的頁面是不全的,只有大概2k多數據。所以在實際應用中我使用了read作為接收函數。

我的需求是通過上證股票代碼獲得開盤收盤和當前價格等信息,已知新浪股票的HTTP接口用法是這樣 http://hq.sinajs.cn/?list=sh600000,sh600406 放到瀏覽器一看就明白了,已經滿足通過代碼獲的所有信息,接下來寫具體的處理過程。

下面是我所寫的通過股票代碼獲得實時價格的程序:

由於涉及自己伺服器數據庫的數據結構,數據庫處理過程已經省略。getline得到的每一行可以用sscanf分隔成字符串,然後再使用atof轉化為價格數的浮點。引號內的字段可以分別保存到zd[33][50]的二位數組中,關於新浪的股票接口,它們每個字段表示的意義大概如下:
0股票名稱;1今開價;2昨收價;3當前價;4今最高;5今最低;……最後是30更新日期和31時間

自用程序寫的比較爛,如有缺陷歡迎指正。
=======
kujou_rin

C語言接口遠程讀取MySQL數據實例

  之前在伺服器上搭建了VPN之後,順便寫了一個php的註冊頁面用於註冊VPN的用戶,使用MySQL保存用戶數據。而pptpd和l2tpd服務則在另一台伺服器運行,且通過文件進行用戶驗證。因此需要將用戶密碼表單遠程從MySQL中取出並在VPN伺服器保存為文件。我的解決方案是使用C語音調用MySQL接口然後使用文件流保存,這樣的方案同樣可用於解決架設多節點的VPN服務。

實例代碼如下:

Makefile文件內容如下:

然後只需要再寫一個shell腳本添加到 crontab 定時運行該程式並將輸出的文件移動為 chap-secrets 即可。

簡易的VPN用戶管理系統就大功告成了~

======
kujou_rin