Here is my code of ftp server. And I just extract the
implement of the function of transfering files.
I know it is very awful, so I am here to asked for your
help.
namespace FtpSrvr
{
public class Form1 : System.Windows.Forms.Form
{
private bool srv = true;
private IPAddress ipAddr;
private IPEndPoint ipEP;
public Socket sock_accpt;//port 20
public Socket sock_daccpt;//port 21
private Thread thrd_accpt;//a thread to accept connection
private Thread thrd_Daccpt;
public int total =0;
..........
[STAThread]
static void Main()
{Application.Run(new Form1()); }
................
private void btStartSrvr_Click(object sender,
System.EventArgs e)
{
this.btStartSrvr.Enabled = false;
ipAddr = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEP1 = new IPEndPoint(ipAddr,20);
sock_accpt = new Socket
(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.
Tcp);
sock_accpt.Bind((EndPoint)ipEP1);
sock_accpt.Listen(5);
//
IPEndPoint ipEP2 = new IPEndPoint(ipAddr,21);
sock_daccpt = new Socket
(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.
Tcp);
sock_daccpt.Bind((EndPoint)ipEP2);
sock_daccpt.Listen(5);
//create new thread to accept connection
thrd_Accpt = new Thread(new ThreadStart(this.Thrd_Accpt));
thrd_Accpt.Start();
}
private void Thrd_Accpt()
{
while(srv)//
{ Socket newClient = sock_accpt.Accept();
ThreadStartCommand c = new ThreadStartCommand
(newClient,this.sock_daccpt);
Thread thrd = new Thread(new ThreadStart(c.Thrd_Command));
thrd.Start();
}
}
internal class ThreadStartCommand
{
private Socket _sock;//store the socket created by accept()
private Form1 _form;
public ThreadStartCommand(Socket sock, Form1 form
{ _sock = sock;
_form = form;
}
//this function aims to retrevie command
public void Thrd_Command()
{
_sock.SetSocketOption
(SocketOptionLevel.Socket,SocketOptionName.SendTimeout,5000
);
byte[] b= System.Text.Encoding.ASCII.GetBytes("welcome to
my ftp server");
try
{
_sock.Send(b,0,b.Length,SocketFlags.None);
}
catch(SocketException ex)
{
System.Diagnostics.Debug.Write("error to send welcome
message" );
return;
}
_sock.SetSocketOption
(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,2
0000);
byte[] buffer = new byte[1024];
int rcv ;
while(true)
{
try
{
rcv = _sock.Receive(buffer,0,1024,SocketFlags.None);
}
catch(SocketException ex)
{
/*if the client doesn't send command within 20 seconds,the
socket will close.*/
_sock.Close();
return
}
}
string s = System.Text.Encoding.ASCII.GetString
(buffer,0,rcv);
s = s.ToLower();
int i = s.IndexOf(" ");
string comCode = s.Substring(0,i);
string para = s.Substring(i+1,rcv-1-i);
AnalyseCommand(comCode,para);
byte[] buffer = ASCII.GetBytes("120 new port allocated");
_sock.Send(buffer,0,buffer.Length,SocketFlags.None);
}
}
public void AnalyseCommand(string comCode, string para)
{
switch(comCode)
{
case "retr":
{
lock(this._form.sock_daccpt)//
{if(this._form.total<4)
this._form.total++;//restrict total connection of Port 21
else
{byte[] buf = System.Text.Encoding.ASCII.GetBytes("sorry,
overload");
this._sock.Send(buf,0,buf.Length,SocketFlags.None);
return;
}
}
Thread thrd = new Thread(new ThreadStart
(this.ThrdSndFile));
thrd.Start();// thread to transfer file to client
}
break;
}
case "":...
case "":...
}
}
public void ThrdSndFile(Socket accpt, string para)
{
Socket dataclient = this._form.sock_daccpt.Accept();
FileStream fs;
try
{
fs = new FileStream
(@para,FileMode.Open,FileAccess.Read,FileShare.Read);
}
catch(IOException ex)
{dataclient.Close();
return;
}
dataclient.SetSocketOption
(SocketOptionLevel.Socket,SocketOptionName.SendTimeout,5000
0);
int rd = 1;
while(rd!=0)
{
//Question:if the client socket collapse, what happen to
//socket of server, does it still push data to TCP's buffer
byte[] buffer = new byte[1024];
rd = fs.Read(buffer,0,1024);
try
{_sock.Send(buffer,0,rd,SocketFlags.None);
}
catch(SocketException ex)
{
lock(this._form._sock_daccpt)
{ this._form.total--;
}
_sock.Close();
return;
}
}
}
_sock.Close();
}
}
}