using System;
using System.IO;
using System.Net.Sockets;
namespace ftpClientUtil
{
internal class FtpWebStream : Stream
{
private FtpWebResponse response;
private NetworkStream dataStream;
public FtpWebStream(NetworkStream dataStream, FtpWebResponse response)
{
this.dataStream = dataStream;
this.response = response;
}
public override void Close()
{
response.Close();
base.Close();
}
public override void Flush()
{
dataStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return dataStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException("Seek not supported.");
}
public override void SetLength(long value)
{
throw new NotSupportedException("SetLength not supported.");
}
public override void Write(byte[] buffer, int offset, int count)
{
dataStream.Write(buffer, offset, count);
}
public override bool CanRead
{
get { return dataStream.CanRead; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return dataStream.CanWrite; }
}
public override long Length
{
get { throw new NotSupportedException("Length not supported."); }
}
public override long Position
{
get
{
throw new NotSupportedException("Position not supported.");
}
set
{
throw new NotSupportedException("Position not supported.");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
namespace ftpClientUtil
{
public class FtpWebRequest : WebRequest
{
private string username = "anonymous";
internal string password = "someuser@someemail.com";
private Uri uri;
private bool binaryMode = true;
private string method = "Get";
internal FtpWebRequest(Uri uri)
{
this.uri = uri;
}
public string Username
{
get { return username; }
set { username = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
public bool BinaryMode
{
get { return binaryMode; }
set { binaryMode = value; }
}
public override System.Uri RequestUri
{
get
{
return uri;
}
}
public override string Method
{
get
{
return method;
}
set
{
method = value;
}
}
public override WebResponse GetResponse()
{
FtpWebResponse response = new FtpWebResponse(this);
return response;
}
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace ftpClientUtil
{
public class FtpWebResponse : WebResponse
{
private FtpWebRequest request;
private FtpClient client;
internal FtpWebResponse(FtpWebRequest request)
{
this.request = request;
}
public override Stream GetResponseStream()
{
string hostname;
string filename;
GetUriComponents(request.RequestUri.ToString(), out hostname, out filename);
//Connect to the Ftp server and get a stream
client = new FtpClient(request.Username, request.password);
client.Connect(hostname);
NetworkStream dataStream = null;
switch (request.Method)
{
case "Get":
case "RETR":
dataStream = client.GetReadStram(filename, request.BinaryMode);
break;
case "PUT":
case "STOR":
dataStream = client.GetWriteStream(filename, request.BinaryMode);
break;
default:
throw new WebException("Method " + request.Method + " not supported");
}
//create and return an FtpWebStream (to close the underlying objects)
FtpWebStream ftpStream = new FtpWebStream(dataStream, this);
return ftpStream;
}
private void GetUriComponents(string uri, out string hostname, out string fileName)
{
//Check that URI has at least 7 characters, or we'll get an error
uri = uri.ToLower();
if (uri.Length < 7)
throw new UriFormatException("Invalid URI");
//Check that URI starts "ftp://", and remove that from the start
if (uri.Substring(0,6)!="ftp://")
throw new NotSupportedException("Only FTP requests are supported");
else
uri=uri.Substring(6,uri.Length-6);
//Divide the rest of the URI into the hostname and the filename
string[] uriParts = uri.Split(new char[]{'/'},2);
if (uriParts.Length != 2)
throw new UriFormatException("Invalid URI");
hostname = uriParts[0];
fileName = uriParts[1];
}
public override void Close()
{
client.Close();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
namespace ftpClientUtil
{
public class FtpRequestCreator : IWebRequestCreate
{
public FtpRequestCreator()
{ }
public System.Net.WebRequest Create(System.Uri uri)
{
return new FtpWebRequest(uri);
}
}
}
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
namespace ftpClientUtil
{
internal sealed class FtpClient
{
private const int bufferSize = 65536;
private NetworkStream controlStream;
private NetworkStream dataStream;
private TcpClient client;
private string username;
private string password;
private TcpClient dataClient = null;
public FtpClient(string username, string password)
{
this.username = username;
this.password = password;
}
public void Connect(string hostname)
{
//Set the private fields representing the TCP control connection to
//the server and the NetworkStream used to communicate with the server
client = new TcpClient(hostname, 21);
controlStream = client.GetStream();
string responseMessage;
if (GetResponse(out responseMessage) != 220)
{
throw new WebException(responseMessage);
}
Logon(username, password);
}
public int GetResponse(out string responseMessage)
{
//Read the response from the server, trim any nulls, and return it.
byte[] response = new byte[client.ReceiveBufferSize];
controlStream.Read(response, 0, response.Length);
responseMessage = Encoding.ASCII.GetString(response).Replace("/0", "");
return int.Parse(responseMessage.Substring(0, 3));
}
private void Logon(string username, string password)
{
//Send a USER FTP commnad. The server should repond with a 331 message to ask for the user's password
string respMessage;
int resp = SendCommand("USER " + username, out respMessage);
if (resp != 331 && resp != 230)
throw new UnauthorizedAccessException("Unable to login to the FTP server");
if (resp != 230)
{
//Send a PASS FTP command. The server should respond with a 230 message to say that the user is now logged in.
resp = SendCommand("PASS " + password, out respMessage);
if (resp != 230)
throw new UnauthorizedAccessException("FTP server can't authenticate username");
}
}
public NetworkStream GetReadStram(string filename, bool binaryMode)
{
return DownloadFile(filename, binaryMode);
}
public NetworkStream GetWriteStream(string filename, bool binaryMode)
{
return UploadFile(filename, binaryMode);
}
public NetworkStream DownloadFile(string filename, bool binaryMode)
{
if (dataClient == null)
dataClient = CreateDataSocket();
SetBinaryMode(binaryMode);
string respMessage;
int resp = SendCommand("RETR " + filename, out respMessage);
if (resp != 150 && resp != 125)
throw new WebException(respMessage);
dataStream = dataClient.GetStream();
return dataStream;
}
private NetworkStream UploadFile(string filename, bool binaryMode)
{
if (dataClient == null)
dataClient = this.CreateDataSocket();
//Set binary or ASCII mode
SetBinaryMode(binaryMode);
//Send a STOR command to say we want to upload a file
string respMessage;
int resp = SendCommand("STOR " + filename, out respMessage);
//we should get a 150 resposne to say that the server is opening the data connection
if (resp != 150 && resp != 125)
throw new WebException("Can't upload file to the server");
dataStream = dataClient.GetStream();
return dataStream;
}
private void SetBinaryMode(bool binaryMode)
{
int resp;
string respMessage;
if (binaryMode)
resp = SendCommand("TYPE I", out respMessage);
else
resp = SendCommand("TYPE A", out respMessage);
if (resp != 200)
throw new WebException(respMessage);
}
private TcpClient CreateDataSocket()
{
//request server to listen on a data port (not the default data port) and wait for a connection
string respMessage;
int resp = SendCommand("PASV", out respMessage);
if (resp != 227)
throw new WebException(respMessage);
//The response includes the host address and port numner
//IP address and port numner separated with ',' Create the IP address and port number
int[] parts = new int[6];
try
{
int index1 = respMessage.IndexOf('(');
int index2 = respMessage.IndexOf(')');
string endPointData = respMessage.Substring(index1+1,index2-index1-1);
string [] endPointParts = endPointData.Split(',');
for (int i=0;i<6;i++)
parts[i] = int.Parse(endPointParts[i]);
}
catch
{
throw new WebException("Malformed PASV reply: " + respMessage);
}
string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
int port = (parts[4] << 8) + parts[5];
//Create a client socket
TcpClient dataClient = new TcpClient();
//Connect to the data poer of the server
try {
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipAddress),port);
dataClient.Connect(remoteEP);
}
catch (Exception)
{
throw new WebException("Can't connected to remote server");
}
return dataClient;
}
public void Close()
{
if (dataStream != null)
{
dataStream.Close();
dataStream = null;
}
string respMessage;
GetResponse(out respMessage);
Logoff();
//Close the control TcpClient and NetworkStream
controlStream.Close();
client.Close();
}
public void Logoff()
{
//Send the QUIT command to log off from the server
string respMessage;
SendCommand("STAT", out respMessage); //Test only
GetResponse(out respMessage); //STAT has 2 response lines!
SendCommand("QUIT", out respMessage);
}
internal int SendCommand(string command, out string respMessage)
{
//Convert the command string (terminated with a CRLF) into a byte array, and write it to control stream.
byte[] request = Encoding.ASCII.GetBytes(command + "/r/n");
controlStream.Write(request, 0, request.Length);
return GetResponse(out respMessage);
}
}
}
以下是客户端的调用:
using System;
using System.IO;
using System.Net;
using ftpClientUtil;
namespace ConsoleApplication1
{
class Program
{
const int bufferSize = 65536;
static void Main(string[] args)
{
//Register the ftp schema.
//Alternatively, a config file could be used
WebRequest.RegisterPrefix("ftp", new FtpRequestCreator());
//UploadDemo();
}
//Upload a file using FtpWebRequest
public static void UploadDemo()
{
ftpClientUtil.FtpWebRequest req = (ftpClientUtil.FtpWebRequest)WebRequest.Create("ftp://192.168.0.1/demofile.bmp");
req.Username = "Administrator";
req.Password = "secret";
req.Method = "PUT"; //STOR or PUT
req.BinaryMode = true;
Stream writeStream = req.GetResponse().GetResponseStream();
FileStream fs = new FileStream(@"c:/temp/cool.bmp", FileMode.Open);
byte[] buffer = new byte[bufferSize];
int read;
while ((read = fs.Read(buffer, 0, bufferSize)) > 0)
writeStream.Write(buffer, 0, bufferSize);
writeStream.Close();
fs.Close();
}
//Downlaod a file using FtpWebRequest
public static void DownloadDemo()
{
ftpClientUtil.FtpWebRequest req = (ftpClientUtil.FtpWebRequest)WebRequest.Create("ftp://192.168.0.1/sample.bmp");
//defualts:
req.Username = "anonymous";
req.Password = "someuser@somemail.com";
req.BinaryMode = true;
req.Method = "GET";
ftpClientUtil.FtpWebResponse resp = (ftpClientUtil.FtpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//Read a binary file
FileStream fs = new FileStream(@"c:/temp/sample.bmp", FileMode.Create);
byte[] buffer = new byte[bufferSize];
int count;
do
{
Array.Clear(buffer, 0, bufferSize);
count = stream.Read(buffer, 0, bufferSize);
fs.Write(buffer, 0, count);
} while (count > 0);
stream.Close();
fs.Close();
//read a text file
StreamReader reader = new StreamReader(stream);
string line;
while ((line = reader.ReadLine()) != null)
Console.WriteLine(line);
reader.Close();
}
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace TCPServerDemo
{
class ClientHandler
{
public TcpClient clientSocket;
public void RunClient()
{
//Create the stream classes
Console.WriteLine(clientSocket.Client.AddressFamily.ToString());
StreamReader readerStream = new StreamReader(clientSocket.GetStream());
NetworkStream writestream = clientSocket.GetStream();
string returnData = readerStream.ReadLine();
string userName = returnData;
Console.WriteLine("Welcome " + userName + " to the Server");
while (true)
{
returnData = readerStream.ReadLine();
if (returnData.IndexOf("QUIT") > -1)
{
Console.WriteLine("Bye Bye " + userName);
break;
}
Console.WriteLine(userName + ": " + returnData);
returnData += "/r/n";
byte[] dataWrite = Encoding.ASCII.GetBytes(returnData);
writestream.Write(dataWrite, 0, dataWrite.Length);
}
clientSocket.Close();
}
}
public class EchoServer
{
const int ECHO_PORT = 8080;
public static int nClient = 0;
static void Main(string[] args)
{
try
{
//Bind the Server to local port
TcpListener clientListener = new TcpListener(IPAddress.Parse("127.0.0.1"),ECHO_PORT);
//start to listen
clientListener.Start();
Console.WriteLine("Waiting for connection...");
while (true)
{
//Accept the connection
TcpClient client = clientListener.AcceptTcpClient();
ClientHandler cHandler = new ClientHandler();
//pass value to the ClientHandler object
cHandler.clientSocket = client;
string ipaddressport = client.Client.RemoteEndPoint.ToString();
Console.WriteLine(ipaddressport.Substring(0, ipaddressport.IndexOf(":")) + "--------------"+ipaddressport.Substring(ipaddressport.IndexOf(":")+1), ipaddressport.Length - ipaddressport.IndexOf(":")-1);
//Create a new thread for the client
Thread clientThread = new Thread(new ThreadStart(cHandler.RunClient));
clientThread.Start();
}
clientListener.Stop();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
using System;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Text;
namespace TCPClientDemo
{
class Program
{
const int ECHO_PORT = 8080;
static void Main(string[] args)
{
Console.Write("Your UserName:");
string userName = Console.ReadLine();
Console.WriteLine("-----Logged in-----");
try
{
//Create a connection with the Chatserver
TcpClient eClient = new TcpClient("127.0.0.1", ECHO_PORT);
//Create the stream classes
StreamReader readerStream = new StreamReader(eClient.GetStream());
NetworkStream writeStream = eClient.GetStream();
string dataToSend;
dataToSend = userName;
dataToSend += "/r/n";
//Send username to the server
byte[] data = Encoding.ASCII.GetBytes(dataToSend);
writeStream.Write(data, 0, data.Length);
while (true)
{
Console.WriteLine(userName + ":");
//Read line from server
dataToSend = Console.ReadLine();
dataToSend += "/r/n";
data = Encoding.ASCII.GetBytes(dataToSend);
writeStream.Write(data, 0, data.Length);
//If QUIT is sent, then quit application
if (dataToSend.IndexOf("QUIT") > -1)
break;
string returnData;
//Receive response from server
returnData = readerStream.ReadLine();
Console.WriteLine("Server: " + returnData);
}
//Close TcpClient
eClient.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
TCP也就是基于SOCKET传输,上面是简单的例子,难一些的是把文件拆分,下面是一个UDP的文件传输,改改可以用在上面的TCP上
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Threading;
namespace FileSender
{
public class FileSender
{
//File details (Req. for receiver)
[Serializable]
public class FileDetails
{
public string FILETYPE="";
public long FILESIZE=0;
}
private static FileDetails fileDet = new FileDetails();
//UdpClient - related fields
private static IPAddress remoteIPAddress;
private const int remotePort=5002;
private static UdpClient sender = new UdpClient();
private static IPEndPoint endPoint;
//Filestream object
private static FileStream fs;
[STAThread]
static void Main(string[] args)
{
try
{
//Get remote IP address and create IPEndPoint
//Console.WriteLine("Enter Remote IP address");
remoteIPAddress = IPAddress.Parse("127.255.255.255");// IPAddress.Parse(Console.ReadLine().ToString());
endPoint = new IPEndPoint(remoteIPAddress,remotePort);
//Get file path. (IMP:file size should be less than 8K)
Console.WriteLine("Enter file path and name to send.");
fs = new FileStream(@Console.ReadLine().ToString(), FileMode.Open, FileAccess.Read);
//if (fs.Length > 8192)
//{
// Console.WriteLine("This version transfers files with size <8192 bytes");
// sender.Close();
// fs.Close();
// return;
//}
SendFileInfo();
Thread.Sleep(2000);
//SendFile();
#region big
byte[] a = Encoding.ASCII.GetBytes(((char)3).ToString());
long remainlength = fs.Length - (long)(fs.Length / 8192) * 8192 + 1;
if (fs.Length > 8192)
{
for (int i = 0; i < fs.Length / 8192; i++)
{
byte[] fixbyte = new byte[8192];
fs.Read(fixbyte, 0, 8192);
SendFile(fixbyte);
Console.WriteLine("send " + (i + 1).ToString() + " times");
}
byte[] remainbyte = new byte[remainlength];
fs.Read(remainbyte, 0, (int)remainlength - 1);
Array.Copy(Encoding.ASCII.GetBytes(((char)3).ToString()), 0, remainbyte, remainbyte.Length - 1, 1);
SendFile(remainbyte);
}
#endregion
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void SendFileInfo()
{
//Get file type or extension
fileDet.FILETYPE = fs.Name.Substring((int)fs.Name.Length -3,3);
//Get file length(futrue purpose)
fileDet.FILESIZE = fs.Length;
XmlSerializer fileSerializer = new XmlSerializer(typeof(FileDetails));
MemoryStream stream = new MemoryStream();
//Serialize object
fileSerializer.Serialize(stream,fileDet);
//Stream to byte
stream.Position = 0;
byte[] bytes = new byte[stream.Length];
stream.Read(bytes,0,Convert.ToInt32(stream.Length));
Console.WriteLine("Sending file details...");
//Send file details
sender.Send(bytes, bytes.Length, endPoint);
stream.Close();
}
public static void SendFile()
{
//Creating a file stream
byte[] bytes = new byte[fs.Length];
//stream to bytes
fs.Read(bytes,0,bytes.Length);
Console.WriteLine("Sending file...size=" + fs.Length + " bytes");
try
{
sender.Send(bytes,bytes.Length, endPoint);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
//Clean up
fs.Close();
sender.Close();
}
Console.Read();
Console.WriteLine("File sent sucessfully.");
}
public static void SendFile(byte[] subfilebytes)
{
try
{
sender.Send(subfilebytes, subfilebytes.Length, endPoint);
//Console.WriteLine(Encoding.ASCII.GetString(subfilebytes));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
//sender.Close();
}
Console.WriteLine("Sub File Part sent sucessfully.");
}
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Text;
using System.Xml.Serialization;
namespace FileReceive
{
public class FileRecv
{
[Serializable]
public class FileDetails
{
public string FILETYPE = "";
public long FILESIZE = 0;
}
private static FileDetails fileDet;
//UdpClient vars
private static int localPort = 5002;
private static UdpClient receivingUdpClient = new UdpClient(localPort);
private static IPEndPoint RemoteIpEndPoint = null;
private static FileStream fs;
private static byte[] receiveBytes = new byte[0];
private static byte[] subreceiveBytes = new byte[0];
[STAThread]
static void Main(string[] args)
{
//Get the file details
GetFileDetails();
//Receive file;
ReceiveFile();
}
private static void GetFileDetails()
{
try
{
Console.WriteLine("-----------------Waiting to get File Details!!----------------");
//Receive File info
byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
Console.WriteLine("receive file details!!");
XmlSerializer fileSerializer = new XmlSerializer(typeof(FileDetails));
MemoryStream stream1 = new MemoryStream();
//Received byte to stream
stream1.Write(receiveBytes, 0, receiveBytes.Length);
stream1.Position = 0; //IMP
//call the Deserialize method and cast to the object type
fileDet = (FileDetails)fileSerializer.Deserialize(stream1);
Console.WriteLine("Receive file of type." + fileDet.FILETYPE + " whose size is " + fileDet.FILESIZE.ToString() + " bytes");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void ReceiveFile()
{
int insertpoint=0,i=0;
byte[] a = new byte[1];
try
{
receiveBytes = new byte[fileDet.FILESIZE];
Console.WriteLine("--------------Waiting to get File-------------------");
//Receive file
//receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
//Console.WriteLine("------File received...Saving....");
////Create temp file from received file extension
//fs = new FileStream("temp." + fileDet.FILETYPE, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
//fs.Write(receiveBytes, 0, receiveBytes.Length);
//Console.WriteLine("---File Saved----" + receiveBytes.Length.ToString());
//Console.WriteLine("---Opening file with associated program----");
//Process.Start(fs.Name); //Opens file with associated program
#region big
while (true)
{
subreceiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
Array.Copy(subreceiveBytes, subreceiveBytes.Length - 1, a, 0, 1);
string returnData = Encoding.ASCII.GetString(a);
if (returnData.IndexOf((char)3) > -1)
{
Array.Copy(subreceiveBytes, 0, receiveBytes, insertpoint, subreceiveBytes.Length - 1);
//Convert and display data
Console.WriteLine("------File received...Saving....");
//Create temp file from received file extension
fs = new FileStream("temp." + fileDet.FILETYPE, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
fs.Write(receiveBytes, 0, receiveBytes.Length);
Console.WriteLine("---File Saved----" + receiveBytes.Length.ToString());
Console.WriteLine("---Opening file with associated program----");
Process.Start(fs.Name); //Opens file with associated program
}
else
{
i++;
Console.WriteLine(i.ToString());
Array.Copy(subreceiveBytes, 0, receiveBytes, insertpoint, subreceiveBytes.Length);
insertpoint += subreceiveBytes.Length;
}
}
#endregion
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
fs.Close();
receivingUdpClient.Close();
}
}
}
}