Raknet和新版本MySQL相容性問題

來源:互聯網
上載者:User

        先說結論,細節待補充。

        目前發現兩處問題:

1、Raknet內建的AutoPatcher伺服器,初始化DB時有一句:

"modificationDate double precision DEFAULT EXTRACT(EPOCH ......),"

(AutopatcherMySQLRepository.cpp  Line 83)

根據百度來的說法,MySQL不支援以函數作為預設值。所以這個地方運行時會報錯,我將其改為DEFAULT 0.0,然後修改代碼。

具體是在同一個檔案兩處調用“INSERT INTO FileVersionHistory”的時候,顯式的給modificationDate賦值,利用C語言標準庫的time.h獲得目前時間放進去就可以了。

這麼以來,資料庫表建立似乎是ok了,但發現下載不了。

2、用戶端下載patcher時,每次伺服器傳來的都是0位元組資料,根本不能下載。

Raknet代碼還是挺複雜的,連續調試了兩三天代碼,發現問題還是出在 AutopatcherMySQLRepository.cpp 這個檔案,下面這句:

sprintf(query, "SELECT substring(content from %i for %i) FROM FileVersionHistory WHERE fileId=%i;", startReadBytes+1,numBytesToRead,context.fileId);

這句查詢會失敗,原因還不清楚。晚上或者明天補充一下。

———————————咚咚咚,次日—————————————————————————————————————————————————————————

        AutoPatcher不能用的問題基本搞定了,先說結論:Raknet底層操作MySQL資料庫時,串連用的參數處理不當,導致在Linux下二次串連資料庫會失敗。

        遇到複雜問題都得先從基本程式開始做做實驗:

//我自己寫的測試代碼:#include "MySQLInterface.h"#include <stdio.h>#include "mysql/mysql.h"  // MYSQL_RESint main(){    MySQLInterface sql;    bool success = sql.Connect("localhost", "root", "1", "swift", 0, NULL, 0);    if (!success)    {        printf("failed connect: %s\n", sql.GetLastError());        return -1;    }    else    {        printf("connected: %d\n", sql.IsConnected());    }}

        如上,利用Raknet對MySQL的簡單封裝,寫出來的串連操作就是上面黑體字那樣的。注意倒數第二個參數:unix_socket,這個參數如果不需要,必須為NULL而不能是空字串"",空字串會導致串連失敗。您先別急試,傳NULL會導致MySQLInterface的底層崩潰,是這麼崩的:

// DependentExtensions/MySQLInterface/MySQLInterface.cppbool MySQLInterface::Connect(const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag){if (IsConnected())return false;_host=host;_user=user;_passwd=passwd;_db=db;_port=port;_unix_socket=unix_socket;_clientflag=clientflag;mySqlConnection = mysql_init(0);return mysql_real_connect (mySqlConnection, host, user, passwd, db, port, unix_socket, clientflag) != 0;}
//其中,這些底線開頭的成員的類型為:// Copy of connection parametersRakNet::RakString _host;RakNet::RakString _user;RakNet::RakString _passwd;RakNet::RakString _db;unsigned int _port;RakNet::RakString _unix_socket;unsigned long _clientflag;



        也就是說,它們是RakString類型,無法表示NULL,而且賦值為NULL會導致Segmentation fault。

        另外,在下載Patcher的時候,調用的是:

//AutopatcherMySQLRpository.cpp 函數AutopatcherMySQLRepository::GetFilePart的片段:if (filePartConnection==0){filePartConnection = mysql_init(0);mysql_real_connect(filePartConnection, _host, _user, _passwd, _db, _port, _unix_socket, _clientflag);

        一來,上面說了這個_unix_socket不是NULL,會導致連不上,而且沒有判斷是否成功。非常難查。

        二來,發現了嗎,RakString傳參時可以直接當作C字串來用,這個設計值得學習。如果像我一樣覺得不爽,就用RakString的C_String()方法轉換成正確的類型。

        總之是個很討厭的問題。而且還不是很好改。我最大的收穫是通過這個BUG把Raknet源碼好好跟了下 :)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.