Page 1 of 1
When wxSocket transmiss a file which class should i use?
Posted: Thu Jan 06, 2011 1:14 pm
I use wxSocketClient transmiss a file to wxSocketServer,when the file's length less than 8688 bytes,they work well,otherwise,wxSocketServer will read 8688 bytes at most.
So when transmiss a file which class should i use? wxSocketClient or wxSocketOutputStream/wxSocketInputStream ?
Posted: Thu Jan 06, 2011 4:23 pm
Please post some code; sockets are streams so have theorically no transfer limit. I thus suppose that you sending and/or reading code is incorrect
Posted: Fri Jan 07, 2011 11:48 am
ok! I use wxThread in wxSocketClient,when drop files on wxTextCtrl,the thread will be run.
First i write 1 byte to tell wxSocketServer that 1 is a file,and then 4 bytes to tell wxSocketServer file'size,and then 50 bytes is the file's name,and last is file data that need to be saved.
here is the code that in wxSocketClient program:
Code: Select all
his->m_arrFileName is the array that when drop files on wxTextCtrl
for(size_t i=0; i<this->m_arrFileName.GetCount(); i++)
wxString filePath = this->m_arrFileName[i];//files path
wxString fileName = wxFileNameFromPath(filePath);//file name
const wxChar* pName = fileName.c_str();//wxChar* file name
size_t fileSize = file.Length();//file;size
wxUint8 type = 1;//1=>file,0=>text
memoryBuffer.AppendData(&fileSize,4);//append file size
memoryBuffer.AppendData(pName,50);//append file name
wxUint8* buffer = new wxUint8[fileSize];
size_t len = file.Read(buffer,fileSize);//read file data into wxMemoryBuffe
memoryBuffer.AppendData(buffer,len);//append file data
size_t length = memoryBuffer.GetDataLen();//data'length that need to send
wxUint8* data = (wxUint8*)memoryBuffer.GetData();//data
this->m_socket->Write(data,length);//Write data to wxSocketServer
When wxSocketServer receive socket event,it will start a new thread.
First it read 1 byte to know the type of socket data,and then 4 bytes to know the data length ,last is the data.
Here is the code that in wxSocketServer:
Code: Select all
if(type == 0)//text that should show on gui
size_t length;//wxChar length
wxChar* buffer = new wxChar[length/2];
//wxMessageBox(wxString::Format(wxT("Type: %d,Length: %d,Value: %s,Receive: %d"),type,length,s.c_str(),this->m_socket->LastCount()));
else if(type == 1)//a file
size_t length;//wxFile length
wxChar* pName = new wxChar[50/2];//file'name
wxString fileName(pName);//wxString file name
wxUint8* buffer = new wxUint8[length];//buffer
wxFile file;//create a new file
/*wxMessageBox(wxString::Format(wxT("Type: %d,Length: %d,FileName: %s"),type,length,pName));*/
I use codeblocks wx2.8.11 unicode multi gcc dll .the project is in attachment.
Posted: Fri Jan 07, 2011 2:30 pm
Either you configure your socket in blocking mode (http://biolpc22.york.ac.uk/wx/docs/html ... sesetflags
) or you should write a more complex code.
Your problem is that you fills the output buffer and the socket truncates the sent data. If you want to send everyting with a single command, you should configure your socket in blocking mode. But, in this case, the GUI will be blocked until everything is sent.
If you do not want the GUI to be blocked, you have to check how many bytes were sent (with wxSocketBase::LastCount) and send remaining data when there is space in output buffer.
Posted: Sat Jan 08, 2011 4:04 pm
I use wxSoketClient::SetFlags(wxSOCKET_BLOCK) and wxSocketServer::SetFlags(wxSOCKET_BLOCK) before read.
but result is the same.
Posted: Sat Jan 08, 2011 10:23 pm
Do you provide wxSOCKET_WAITALL flag also ?
Posted: Wed Jan 12, 2011 1:20 am
Yes.but still the same result.
On wxSocketServer program, when it read bytes less than 8000 each time,the project work well.
Posted: Thu Jan 13, 2011 5:10 pm
There is no guaranty that all of the data will show up at the same time.
You should be checking LastCount after every read to ensure that you actually did read some data.
In your type==1 condition you should do something like the following in place of
wxUint32 u32Rcvd = 0;
while (u32Rcvd < length)
this->m_socket->Read(buffer + u32Rcvd,length - u32Rcvd);
u32Rcvd += this->m_socket->LastCount();
// Maybe check for error here with this->m_socket->Error and LastError
// Maybe sleep a bit here to take load off cpu.
Hope this helps.