我已经为我的 FTP 创建了一个聊天程序和一个创建的 GUI。我已经编写了我认为适用于 FTP 的代码,但是当我运行该解决方案时,它总是给我不同的结果。也就是说,它每次都创建具有不同内存集的文件。这是相关的编码,当它被传输回客户端时,问题似乎发生了:
在服务器中:
//Listens for new commands coming in from the client associated with the client object
public void Command_Listener()
{
foreach (Client C in UI[0].clients)
{
sw.WriteLine("2: User: " + username + " has connected...");
sw.Flush();
//Notifies other client objects inside the user interface that this one is operational
}
while (UI[0].busy)
{ } //waits for the log to not be busy with another task then declares this task is over
UI[0].busy = true;
UI[0].Log_Event(username + " has connected..." + DateTime.Now.ToString());
UI[0].Log_Event("Client username : " + Client_Info[0]);
UI[0].Log_Event("Client computer name : " + Client_Info[1]);
UI[0].Log_Event("Client operating system : " + Client_Info[2]);
UI[0].Log_Event("Client lan IP address : " + Client_Info[3]);
UI[0].Log_Event("Client wan IP address : " + Client_Info[4]);
//sends the client info from the client to the server's user interface and the log
UI[0].busy = false;
while (true)
{
try
{
string command = sr.ReadLine();
//waits for a new message
if (command[0] == '1')
Update_Chat_List(command.Replace("1: ", ""));
//Determines the Username has changed and needs to update the list
if (command[0] == '2')
Update_Message_Board(command.Replace("2: ", ""));
//Determines the message board on each clients needs to update with the new command included
if (command == "3: typing" && !typing) //Determines the client's typing
{
typing = true;
Update_Chat_List(username);
}
if (command == "3: empty" && typing) //Determine the client's not typing
{
typing = false;
Update_Chat_List(username);
}
if (command[0] == '5') //Determines that a new FTP is in progress
Update_FTP_Status(command.Replace("5: ", ""));
if (command[0] == '6')
{
//Adds the incoming kilobyte of the file to a string list
kilos.Add(command.Replace("<heartbeat>", ""));
}
if (command[0] == '7')
{
//Tells the server that all pieces of the file have been recieved
kilos.Add(command);
new Thread(Send_File).Start();
}
}
catch //catchs all listening problems and tells the server the client must be removed and then does a user list update and logs the exit
{
sw.Dispose();
sr.Dispose();
UI[0].clients.RemoveAt(Client_Index);
UI[0].Update_Index();
while (UI[0].busy)
{ }
UI[0].busy = true;
UI[0].Log_Event(username + " has disconnected...");
UI[0].busy = false;
foreach (Client C in UI[0].clients)
{
C.sw.WriteLine("2: " + username + " has disconnected...");
C.sw.Flush();
}
Update_Chat_List("");
return;
}
}
}
public void Send_File()
{
string last = "";
foreach (string kilo in kilos)
{
FTP_Connection[0].sw.WriteLine(kilo);
FTP_Connection[0].sw.Flush();
//sends all part of the file and the closing compile command for the client
}
ftping = false;
int length = last.Length;
FTP_Connection[0].ftping = false;
//changes ftp status to off
}
public void Update_FTP_Status(string user)
{
string filename = "";
bool building = false;
foreach (char c in user)
{
if (building)
filename = filename + c;
else if (c == ':')
building = true;
}
//retrieves the filename
user_to_send_to = user.Replace(":" + filename, "");
//replaces the filename out of the message to get the user to send to
foreach (Client User in UI[0].clients)
{
if (User.username == user_to_send_to)
{
User.sw.WriteLine("5: " + username);
User.sw.Flush();
User.sw.WriteLine(filename);
User.sw.Flush();
FTP_Connection.Add(User);
//notifies the client they are recieving a file then setups a direct access to the client the ftp is going to.
}
}
}
在客户端:
//Listens for new commands given by the server
void Command_Listener()
{
Connected = true;
while (true)
{
try
{
string Comunicae = sr.ReadLine();
//recieves the message
if (Comunicae[0] == '1')
User_List_Update(Comunicae.Replace("1: ", ""));
//Determines the user list has to be updated
if (Comunicae[0] == '2')
New_Message(Comunicae.Replace("2: ", ""));
//Determines the messages board has to be updated
if (Comunicae[0] == '4')
New_Server_Command(Comunicae.Replace("4: ", ""));
if (Comunicae[0] == '5') //notifies the user theres a new ftp incoming
{
ftping = true;
string filenam = sr.ReadLine();
File_Name = filenam;
FTP_Sender = Comunicae.Replace("5: ", "");
Recipients_Message = Comunicae.Replace("5: ", "") + " is sending you " + filenam + " file via ftp...\r\nYou will recieve this file in " + settings[0].driver + "program data\\";
}
if (Comunicae[0] == '6')
{
int length = Comunicae.Length;
lengths.Add(length);
string kilo = Comunicae.Replace("6: ", "");
kilos.Add(kilo);
//gathers the incoming file parts
}
if (Comunicae[0] == '7')
{
new Thread(Compile_File).Start();
//Pieces together the file
}
}
catch (Exception E)
{
//Kills the client if theres a reading error
Process.GetCurrentProcess().Kill();
return;
}
}
}
void Compile_File()
{
int length = kilos[kilos.Count - 1].Length;
List<byte> file = new List<byte>();
foreach (string kilo in kilos) //seperates out each byte in each file part then adds to the byte list
{
string byt = "";
int helper = 0;
foreach (char C in kilo)
{
if (helper == 3)
{
string temp = byt;
file.Add(Convert.ToByte(temp));
byt = "";
helper = 0;
}
if (C != '|')
{
byt = byt + C;
}
helper++;
}
}
byte[] final = new byte[file.Count - 1];
for (int i = 0; i != file.Count - 1; i++) //Converts the byte list to an array
{
final[i] = file[i];
}
File.WriteAllBytes(settings[0].driver + "Program Data\\" + File_Name, final);
//Writes the file
ftping = false;
}
private void Send_Click(object sender, EventArgs e)
{
if (Controler[0].ftping) //Detects transfers in progress
{
MessageBox.Show("You already have a file transfer in progress...");
return;
}
if (ftping_users.Contains(User_To_Send_To.Text)) //Detects if the user you try to send to already has a file inbound
{
MessageBox.Show(User_To_Send_To.Text + " is has a inbound or outbound file already in progress...");
return;
}
Controler[0].Update_FTP_Status(User_To_Send_To.Text, Selected_File);
//Aprises the server of a new FTP in progress
byte[] file = File.ReadAllBytes(Current_Directory.Text.Replace(fil, ""));
//Reads the file
Thread T = new Thread(() => Get_Kilos(file));
T.Start();
//Starts segmenting the file bytes and converting them to strings for transfer
this.Hide();
}
public void Get_Kilos(byte[] file)
{
List<string> kilos = new List<string>();
string kilobyte = "";
foreach (byte B in file)
{
string byt = (Convert.ToInt32(B)).ToString();
if (byt.Length == 1)
byt = "||" + byt;
if (byt.Length == 2)
byt = "|" + byt;
kilobyte = kilobyte + byt;
//Makes a bytes string length a standard 3 characters
if (kilobyte.Length == 3072)
{
string temp = "6: " + kilobyte;
kilos.Add(temp);
kilobyte = "";
//Adds the part to a list of file parts
}
}
kilos.Add("6: " + kilobyte);
foreach (string kilo in kilos)
{
int length = kilo.Length;
Controler[0].sw.WriteLine(kilo);
Controler[0].sw.Flush();
//Sends the File parts
}
Controler[0].sw.WriteLine("7: Complete...");
Controler[0].sw.Flush();
//Lets the server know the transfer is complete
Controler[0].ftping = false;
}