在SFML論壇未能獲得任何幫助後,我決定查看是否有人可以獲得幫助。我有一個應用程序,它通過TCP連接更新到服務器應用程序。除了一個特定的數據包傳輸,其中數據包以某種方式被改變之外,這工作得很好。服務器發送一個包含數字1包:我的調試器步進通過正在更改的SFML TCP數據包
pack << sf::Uint8(1);
ClientSocket.Send(pack);
(其中pack
的類型是科幻::包和ClientSocket
的類型是科幻:: SocketTCP)
事實上確實確認這些線路被執行,並且在我的客戶端下一個接收呼叫接下來的幾行:
sock.Receive(pack);
sf::Uint8 conf;
pack >> conf;
(其中pack
再次是SF ::包,sock
是SocketTCP)
但是,在我的客戶端中,conf顯示爲零值(我的調試器確認了這一點),它的行爲如此(下一行根據值切換)。我在同一臺計算機上運行這兩個應用程序,並且它們都互相讀取爲「127.0.0.1」,因此數據包(如果我理解正確)不會通過我的路由器,或者真的離開我的機器。關於爲什麼我的數據包被損壞的任何想法?
爲了記錄,如果有任何幫助,我使用SFML 1.6和我的應用程序在Debian Squeeze Linux機器上運行。
編輯:每個請求,這裏是我的應用程序的一些更多的代碼。
首先,我的客戶的具體涉及到這個更新的部分:
cout << "Connecting to update server." << endl;
sf::IpAddress server = sf::IpAddress::LocalHost;
sf::TcpSocket sock;
if (sock.connect(server, PORT, sf::seconds(20.0f)) != sf::Socket::Done)
return false;
cout << "Connected. Searching for updates for updater." << endl;
sf::Packet pack;
std::string lastUpdate = getLastUpdate();
#ifdef __WXGTK__
pack << "uupdate" << lastUpdate << sf::Uint8(1);
#elif defined(__WXMSW__)
pack << "uupdate" << lastUpdate << sf::Uint8(2);
#elif defined(__WXOSX__)
pack << "uupdate" << lastUpdate << sf::Uint8(3);
#endif
sock.send(pack);
pack.clear();
sock.receive(pack); //THIS IS THE PART WHERE IT BREAKS
sf::Int32 conf;
pack >> conf;
if (conf == 1) { //There is an update!
cout << "Update found!" << endl;
pack << "begin" << sf::Uint32(512);
sock.send(pack);
pack.clear();
sock.receive(pack);
pack >> conf;
if (conf == 0) { //No errors
wxFileOutputStream* out = new wxFileOutputStream(wxString(UPDATER, StrConv).append(".temp"));
char* data = new char[512];
while (data != chara("done") && data != chara("error")) {
sock.receive(pack);
sf::Int32 size;
pack >> size;
data = const_cast<char*>((const char*)pack.getData());
out->Write(data, size);
}
out->Close();
if (data == chara("done"))
wxCopyFile(wxString(UPDATER, StrConv).append(".temp"), wxString(UPDATER, StrConv));
wxRemoveFile(wxString(UPDATER, StrConv).append(".temp"));
}
}
cout << "Updater is up-to-date. Executing updater." << endl;
sock.disconnect();
bool success;
if (wxTheApp->argc == 1)
success = wxExecute(wxT(UPDATER));
else
success = wxExecute(wxString(UPDATER, StrConv).append(wxTheApp->argv[1]));
return success;
,然後服務器有關這些更新的部分:
//ClientSocket has already been initalised by way of a TcpListener
cout << "Checking for updater patches for client at " << ClientAddress.toString() << endl;
std::string lastUpdate;
pack >> lastUpdate;
sf::Uint8 os;
pack >> os;
//Check last time updater was changed
struct tm* clock;
struct stat attribs;
if (os == 1)
stat("Linux/Updater", &attribs);
else if (os == 2)
stat("Windows/Updater.exe", &attribs);
else if (os == 3)
stat("Mac/Updater", &attribs);
clock = gmtime(&(attribs.st_mtime));
time_t lastWrite = mktime(clock);
time_t clientUpdate = stringToNumber<time_t>(lastUpdate.c_str());
if (lastWrite > clientUpdate) {
cout << "Found updater patches for client at " << ClientAddress.toString() << endl;
pack << sf::Int32(1);
ClientSocket->send(pack); //THIS IS THE PART WHERE IT BREAKS
pack.clear();
ClientSocket->receive(pack);
std::string mes;
pack >> mes;
if (mes != "begin") {
cerr << "Client at " << ClientAddress.toString() << " sent unrecognised message: " << mes << ". Ending conversation." << endl;
ClientSocket->disconnect();
return false;
}
sf::Uint32 size;
pack >> size;
cout << "Beginning to send updater patch to " << ClientAddress.toString() << endl;
ifstream in;
if (os == 1)
in.open(chara("Linux/Updater"), ios_base::in | ios_base::binary);
else if (os == 2)
in.open(chara("Windows/Updater.exe"), ios_base::in | ios_base::binary);
else if (os == 3)
in.open(chara("Mac/Updater"), ios_base::in | ios_base::binary);
if (in.fail()) {
pack << sf::Uint8(1);
ClientSocket->send(pack);
cerr << "Failed to open updater at request of " << ClientAddress.toString() << ". Closing connection." << endl;
ClientSocket->disconnect();
return false;
}
pack << sf::Uint8(0);
ClientSocket->send(pack);
pack.clear();
//Get length of file
in.seekg(0, ios::end);
int length = in.tellg();
in.seekg(0, ios::end);
char* buf = new char[size];
for (unsigned int i = 0; i < length/size; i++) { //Read and send every `size`-sized block we can
in.read(buf, size);
pack << sf::Int32(size) << buf;
ClientSocket->send(pack);
}
in.read(buf, length % size);
pack << sf::Int32(length % size) << buf;
ClientSocket->send(pack);
pack.clear();
pack << "done";
ClientSocket->send(pack);
pack.clear();
} else {
pack << sf::Int8(0);
ClientSocket->send(pack);
}
編輯:我知道這是近一個月以來,在這裏有任何帖子,但我仍然有這個問題。我很機智的結束如何解決這個問題。
你確定你正在閱讀這個包,而不是最後一個的剩菜? – Dani
是的。我正在使用阻塞套接字,並且我確保服務器上的每個發送呼叫都與客戶端上的一個接收呼叫匹配(反之亦然)。我也看到我的客戶端掛在上面顯示的接收呼叫上,直到服務器發送上面顯示的發送呼叫。 更不用說,在那之前的數據包在任何地方都沒有0。 –
嘗試更改數據類型/值以查看它是一切還是隻是uint8。 – Dani