WEB开发网
开发学院软件开发C语言 C#网络编程(订立协议和发送文件) - Part.4 阅读

C#网络编程(订立协议和发送文件) - Part.4

 2009-03-26 08:22:21 来源:WEB开发网   
核心提示: 这里应该没有什么新知识,需要注意的地方有这么几个:在OnReadComplete()回调方法中的foreach循环,C#网络编程(订立协议和发送文件) - Part.4(7),我们使用委托异步调用了handleProtocol()方法,这是因为handleProtocol即将执行的是一个读

这里应该没有什么新知识,需要注意的地方有这么几个:

在OnReadComplete()回调方法中的foreach循环,我们使用委托异步调用了handleProtocol()方法,这是因为handleProtocol即将执行的是一个读取或接收文件的操作,也就是一个相对耗时的操作。

在handleProtocol()方法中,我们深切体会了定义ProtocolHelper类和FileProtocol结构的好处。如果没有定义它们,这里将是不堪入目的处理XML以及类型转换的代码。

handleProtocol()方法中进行了一个条件判断,注意sendFile()方法我屏蔽掉了,这个还没有实现,但是我想你已经猜到它将是后面要实现的内容。

receiveFile()方法是实际接收客户端发来文件的方法,这里没有什么特别之处。需要注意的是文件存储的路径,它保存在了当前程序执行的目录下,文件的名称我使用generateFileName()生成了一个与时间有关的随机名称。

3.2客户端的实现

我们现在先不着急实现客户端S1、R1等用户菜单,首先完成发送文件这一功能,实际上,就是为上一节SendMessage()加一个姐妹方法SendFile()。

class Client {
    static void
Main(string[] args) {
        ConsoleKey key;

        ServerClient client = new ServerClient();
        string filePath = Environment.CurrentDirectory + "/" + "Client01.jpg";

        if(File.Exists(filePath))
            client.BeginSendFile(filePath);
       
        Console.WriteLine("nn输入"Q"键退出。");
        do {
            key = Console.ReadKey(true).Key;
        } while (key != ConsoleKey.Q);
    }
}

public class ServerClient {
    private const int BufferSize = 8192;
    private byte[] buffer;
    private TcpClient client;
    private NetworkStream streamToServer;

    public ServerClient() {
        try {
            client = new TcpClient();
            client.Connect("localhost", 8500);      // 与服务器连接
        } catch (Exception ex) {
            Console.WriteLine(ex.Message);
            return;
        }
        buffer = new byte[BufferSize];

        // 打印连接到的服务端信息
        Console.WriteLine("Server Connected!{0} --> {1}",
            client.Client.LocalEndPoint, client.Client.RemoteEndPoint);

        streamToServer = client.GetStream();
    }

    // 发送消息到服务端
    public void SendMessage(string msg) {

        byte[] temp = Encoding.Unicode.GetBytes(msg);   // 获得缓存
        try {
            lock (streamToServer) {
                streamToServer.Write(temp, 0, temp.Length); // 发往服务器
            }
            Console.WriteLine("Sent: {0}", msg);
        } catch (Exception ex) {
            Console.WriteLine(ex.Message);
            return;
        }
    }

    // 发送文件 - 异步方法
    public void BeginSendFile(string filePath) {
        ParameterizedThreadStart start =
            new ParameterizedThreadStart(BeginSendFile);
        start.BeginInvoke(filePath, null, null);
    }

    private void BeginSendFile(object obj) {
        string filePath = obj as string;
        SendFile(filePath);
    }

    // 发送文件 -- 同步方法
    public void SendFile(string filePath) {

        IPAddress ip = IPAddress.Parse("127.0.0.1");
        TcpListener listener = new TcpListener(ip, 0);
        listener.Start();

        // 获取本地侦听的端口号
        IPEndPoint endPoint = listener.LocalEndpoint as IPEndPoint;
        int listeningPort = endPoint.Port;

        // 获取发送的协议字符串
        string fileName = Path.GetFileName(filePath);
        FileProtocol protocol =
            new FileProtocol(FileRequestMode.Send, listeningPort, fileName);
        string pro = protocol.ToString();

        SendMessage(pro);       // 发送协议到服务端

        // 中断,等待远程连接
        TcpClient localClient = listener.AcceptTcpClient();
        Console.WriteLine("Start sending file...");
        NetworkStream stream = localClient.GetStream();

        // 创建文件流
        FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);          
        byte[] fileBuffer = new byte[1024];     // 每次传1KB
        int bytesRead;
        int totalBytes = 0;

        // 创建获取文件发送状态的类
        SendStatus status = new SendStatus(filePath);

        // 将文件流转写入网络流
        try {
            do {
                Thread.Sleep(10);           // 为了更好的视觉效果,暂停10毫秒:-)
                bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length);                 
                stream.Write(fileBuffer, 0, bytesRead);
                totalBytes += bytesRead;            // 发送了的字节数
                status.PrintStatus(totalBytes); // 打印发送状态
            } while (bytesRead > 0);
            Console.WriteLine("Total {0} bytes sent, Done!", totalBytes);
        } catch {
            Console.WriteLine("Server has lost...");
        }
       
        stream.Dispose();
        fs.Dispose();
        localClient.Close();
        listener.Stop();
    }
}

上一页  2 3 4 5 6 7 8 9  下一页

Tags:网络编程 订立 协议

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接