File using .net sockets, transferring problem
- by Sergei
I have a client and server, client sending file to server. When i transfer files on my computer(in local) everything is ok(try to sen file over 700mb).
When i try to sent file use Internet to my friend in the end of sending appears error on server "Input string is not in correct format".This error appears in this expression fSize = Convert::ToUInt64(tokenes[0]); - and i don't mind wht it's appear. File should be transfered and wait other transferring
ps: sorry for too much code, but i want to find solution
private: void CreateServer()
{
try{
IPAddress ^ipAddres = IPAddress::Parse(ipAdress);
listener = gcnew System::Net::Sockets::TcpListener(ipAddres, port);
listener->Start();
clientsocket =listener->AcceptSocket();
bool keepalive = true;
array<wchar_t,1> ^split = gcnew array<wchar_t>(1){ '\0' };
array<wchar_t,1> ^split2 = gcnew array<wchar_t>(1){ '|' };
statusBar1->Text = "Connected" ;
//
while (keepalive)
{
array<Byte>^ size1 = gcnew array<Byte>(1024);
clientsocket->Receive(size1);
System::String ^notSplited = System::Text::Encoding::GetEncoding(1251)->GetString(size1);
array<String^> ^ tokenes = notSplited->Split(split2);
System::String ^fileName = tokenes[1]->ToString();
statusBar1->Text = "Receiving file" ;
unsigned long fSize = 0;
//IN THIS EXPRESSIN APPEARS ERROR
fSize = Convert::ToUInt64(tokenes[0]);
if (!Directory::Exists("Received"))
Directory::CreateDirectory("Received");
System::String ^path = "Received\\"+ fileName;
while (File::Exists(path))
{
int dotPos = path->LastIndexOf('.');
if (dotPos == -1)
{
path += "[1]";
}
else
{
path = path->Insert(dotPos, "[1]");
}
}
FileStream ^fs = gcnew FileStream(path, FileMode::CreateNew, FileAccess::Write);
BinaryWriter ^f = gcnew BinaryWriter(fs);
//bytes received
unsigned long processed = 0;
pBarFilesTr->Visible = true;
pBarFilesTr->Minimum = 0;
pBarFilesTr->Maximum = (int)fSize;
// Set the initial value of the ProgressBar.
pBarFilesTr->Value = 0;
pBarFilesTr->Step = 1024;
//loop for receive file
array<Byte>^ buffer = gcnew array<Byte>(1024);
while (processed < fSize)
{
if ((fSize - processed) < 1024)
{
int bytes ;
array<Byte>^ buf = gcnew array<Byte>(1024);
bytes = clientsocket->Receive(buf);
if (bytes != 0)
{
f->Write(buf, 0, bytes);
processed = processed + (unsigned long)bytes;
pBarFilesTr->PerformStep();
}
break;
}
else
{
int bytes = clientsocket->Receive(buffer);
if (bytes != 0)
{
f->Write(buffer, 0, 1024);
processed = processed + 1024;
pBarFilesTr->PerformStep();
}
else break;
}
}
statusBar1->Text = "File was received" ;
array<Byte>^ buf = gcnew array<Byte>(1);
clientsocket->Send(buf,buf->Length,SocketFlags::None);
f->Close();
fs->Close();
SystemSounds::Beep->Play();
}
}catch(System::Net::Sockets::SocketException ^es)
{
MessageBox::Show(es->ToString());
}
catch(System::Exception ^es)
{
MessageBox::Show(es->ToString());
}
}
private: void CreateClient()
{
clientsock = gcnew System::Net::Sockets::TcpClient(ipAdress, port);
ns = clientsock->GetStream();
sr = gcnew StreamReader(ns);
statusBar1->Text = "Connected" ;
}
private:void Send()
{
try{
OpenFileDialog ^openFileDialog1 = gcnew OpenFileDialog();
System::String ^filePath = "";
System::String ^fileName = "";
//file choose dialog
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
filePath = openFileDialog1->FileName;
fileName = openFileDialog1->SafeFileName;
}
else
{
MessageBox::Show("You must select a file", "Error",
MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
return;
}
statusBar1->Text = "Sending file" ;
NetworkStream ^writerStream = clientsock->GetStream();
System::Runtime::Serialization::Formatters::Binary::BinaryFormatter ^format =
gcnew System::Runtime::Serialization::Formatters::Binary::BinaryFormatter();
array<Byte>^ buffer = gcnew array<Byte>(1024);
FileStream ^fs = gcnew FileStream(filePath, FileMode::Open);
BinaryReader ^br = gcnew BinaryReader(fs);
//file size
unsigned long fSize = (unsigned long)fs->Length;
//transfer file size + name
bFSize = Encoding::GetEncoding(1251)->GetBytes(Convert::ToString(fs->Length+"|"+fileName+"|"));
writerStream->Write(bFSize, 0, bFSize->Length);
//status bar
pBarFilesTr->Visible = true;
pBarFilesTr->Minimum = 0;
pBarFilesTr->Maximum = (int)fSize;
pBarFilesTr->Value = 0; // Set the initial value of the ProgressBar.
pBarFilesTr->Step = 1024;
//bytes transfered
unsigned long processed = 0;
int bytes = 1024;
//loop for transfer
while (processed < fSize)
{
if ((fSize - processed) < 1024)
{
bytes = (int)(fSize - processed);
array<Byte>^ buf = gcnew array<Byte>(bytes);
br->Read(buf, 0, bytes);
writerStream->Write(buf, 0, buf->Length);
pBarFilesTr->PerformStep();
processed = processed + (unsigned long)bytes;
break;
}
else
{
br->Read(buffer, 0, 1024);
writerStream->Write(buffer, 0, buffer->Length);
pBarFilesTr->PerformStep();
processed = processed + 1024;
}
}
array<Byte>^ bufsss = gcnew array<Byte>(100);
writerStream->Read(bufsss,0,bufsss->Length);
statusBar1->Text = "File was sent" ;
btnSend->Enabled = true;
fs->Close();
br->Close();
SystemSounds::Beep->Play();
newThread->Abort();
}
catch(System::Net::Sockets::SocketException ^es)
{
MessageBox::Show(es->ToString());
}
}
UPDATE: ok, i can add checking if clientsocket->Receive(size1); equal zero, but why he begin receiving data again , in the ending of receiving.
UPDATE:After adding this checking problem remains. AND WIN RAR SAY TO OPENING ARCHIVE - unexpected end of file!
UPDATE:http://img153.imageshack.us/img153/3760/erorr.gif
I think it continue receiving some bytes from client(that remains in the stream), but why existes cicle while (processed < fSize)