客户端程序通过TCP通信传送"小文件"到服务器

源码  (不包含通信框架源码,通信框架源码请另行下载)

上一篇文章写了如何通过TCP通信发送图片到客户端,有朋友问如何传送文件,本文将就如何发送文件进行探讨。

对于比较小的文件,可以把文件转化成字节形式,用契约类包装一下,服务器收到后,再把字节转化成文件即可,这也是本文中实现的方式,这种方式的优点是比较简单灵活,缺点是不适合大文件的发送,也不能显示文件发送的进度。

基于TCP的通信机制,对于比较大的文件,这种方式是不可行的,大文件采用分段发送再合成的方式比较好,以后有时间再对如何发送大文件单独探讨。

本程序基于开源的networkComms2.3.1通信框架

我们先开看一下实现的效果

服务器端:

客户端:

在服务器端,我们把收到的图片保存在D盘根目录下(您可以另外指定路径),打开D盘看到收到的图片如下:

下面看一下具体的过程

第一步,首先进行服务器端的设置

(1)监听端口:

   //服务器开始监听客户端的请求
//开始监听某T端口
IPEndPoint thePoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
TCPConnection.StartListening(thePoint, false);
button1.Text = "监听中";
button1.Enabled = false; //此方法中包含服务器具体的处理方法。
StartListening();

(2) 针对文件上传写对应的处理方法:

   NetworkComms.AppendGlobalIncomingPacketHandler<FileWrapper>("UploadFile", IncomingUploadFile);
   //处理客户端发来的文件
private void IncomingUploadFile(PacketHeader header, Connection connection, FileWrapper wrapper)
{
try
{ writeFile(wrapper._fileData, @"D:\" + wrapper.FileName); ResMsgContract contract = new ResMsgContract();
contract.Message = "上传成功";
//发送回复信息给客户端
connection.SendObject("ResUploadFile", contract); }
catch (Exception ex)
{ }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<span style="color: #008000;">   //此方法来自博客园</span>
        private bool writeFile(byte[] pReadByte, string fileName)
        {
            FileStream pFileStream = null;
            try
            {
                pFileStream = new FileStream(fileName, FileMode.OpenOrCreate);
                pFileStream.Write(pReadByte, 0, pReadByte.Length);
            }
            catch
            {
                return false;
            }
            finally
            {
                if (pFileStream != null)
 
                    pFileStream.Close();
            }
            return true;
        }

  

第二步:客户端的设置

(1)连接服务器:

 //给连接信息对象赋值
connInfo = new ConnectionInfo(txtIP.Text, int.Parse(txtPort.Text)); //如果不成功,会弹出异常信息
newTcpConnection = TCPConnection.GetConnection(connInfo); TCPConnection.StartListening(connInfo.LocalEndPoint); button1.Enabled = false;
button1.Text = "连接成功";

(2)从本地选择文件并上传:

 private void button3_Click(object sender, EventArgs e)
{
openFileDialog2.Filter = "所有文件|*.*"; if (openFileDialog2.ShowDialog() == DialogResult.OK)
{ string shortFileName = System.IO.Path.GetFileName(openFileDialog2.FileName); FileWrapper fileWrapper = new FileWrapper(shortFileName, ReadFile(openFileDialog2.FileName)); //发送图片包装类到服务器,并获取返回信息
ResMsgContract resMessage = newTcpConnection.SendReceiveObject<ResMsgContract>("UploadFile", "ResUploadFile", 8000, fileWrapper); if (resMessage.Message == "上传成功")
{
MessageBox.Show("文件已经上传到服务器");
}
else
{
MessageBox.Show("文件没有发送成功");
} } }

(三)关于FileWrapper类

在客户端与服务器端通信的过程中,我们注意到上面的程序中使用了一个FileWrapper类,用来传递文件对象。

FileWrapper类,存放在MessageContract类库中,此类用来保存文件转化后的二级制数据

using System;
using System.Collections.Generic;
using System.Text;
using ProtoBuf;
using System.Drawing;
using System.IO;
using ProtoBuf; namespace MessageContract
{
[ProtoContract]
public class FileWrapper
{
/// <summary>
/// 把Image对象存储为私有的字节数组
/// </summary>
[ProtoMember(1)]
public byte[] _fileData; /// <summary>
/// 图片名称
/// </summary>
[ProtoMember(2)]
public string FileName { get; set; } /// <summary>
/// 私有的无参数构造函数 反序列化时需要使用
/// </summary>
private FileWrapper() { } /// <summary>
/// 创建一个新的 ImageWrapper类
/// </summary>
/// <param name="imageName"></param>
/// <param name="image"></param>
public FileWrapper(string fileName, byte[] file)
{
this.FileName = fileName;
this._fileData = file;
} }
}

工作到此完成,很少的代码量,就帮我们实现了传递客户端文件保存在服务器的功能。

注意:此种方式并不适合传递比较大的文件,如果文件比较大,最好以分段传送文件的形式发送.

 

客户端程序通过TCP通信传送"小文件"到服务器的更多相关文章

  1. JAVASE02-Unit011: TCP通信(小程序)

    TCP通信(小程序) server端: package chat; import java.io.BufferedReader; import java.io.IOException; import ...

  2. c++下基于windows socket的单线程服务器客户端程序(基于TCP协议)

    今天自己编写了一个简单的c++服务器客户端程序,注释较详细,在此做个笔记. windows下socket编程的主要流程可概括如下:初始化ws2_32.dll动态库-->创建套接字-->绑定 ...

  3. QT 简单 TCP 通信,发送数据到服务器

    1.首先 添加头文件 #include <QtNetwork/QTcpSocket> 并且 在 xxx.pro(xxx指工程的名称) 中QT += core gui下面,添加 下面两句句话 ...

  4. [C语言]一个很实用的服务端和客户端进行TCP通信的实例

    本文给出一个很实用的服务端和客户端进行TCP通信的小例子.具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考. (1)客户端程序,编写一个文件clie ...

  5. 【学习笔记】TCP通信的细节及TCP连接对HTTP事务处理性能影响

    从三次握手的细节说起 刚开始尝试使用java等后端语言写IO流,或用套接字(socket)实现简单C/S通信的同学们,常常会接触到的一个概念:就是所谓的"三次握手",socket作 ...

  6. 【计算机网络】TCP通信的细节及TCP连接对HTTP事务处理性能影响

    从三次握手的细节说起 刚开始尝试使用java等后端语言写IO流,或用套接字(socket)实现简单C/S通信的同学们,常常会接触到的一个概念:就是所谓的“三次握手”,socket作为一个API接口,封 ...

  7. TCP通信 - 服务器开启多线程与read()导致服务器阻塞问题

    TCP通信的文件上传案例 本地流:客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流 网络流:客户端和服务器之间读写,必须使用Socket中提供的字节流对象 客户端工作:读取本地文件,上传到服 ...

  8. Hadoop处理大量小文件的问题和解决方法

    小文件指的是那些size比HDFS的block size(默认64M)小的多的文件.如果在HDFS中存储小文件,那么在HDFS中肯定会含有许许多多这样的小文件(不然就不会用hadoop了).而HDFS ...

  9. 如何利用Hadoop存储小文件

    **************************************************************************************************** ...

随机推荐

  1. etl工具,kettle实现了周期

    Kettle这是国外的来源ETL工具,纯java写.能Window.Linux.Unix在执行.绿色无需安装,稳定高效的数据提取. 业务模型: 在关系型数据库中有张非常大的数据存储表,被设计成奇偶库存 ...

  2. Struts1.X与Spring集成——第一种方案

    spring+struts(第一种方案) 集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象,调用业务逻辑方法. 一,新建一个项目Spring_Strut ...

  3. 按某个字段来分组、编号的row_number()函数

    本文参考 http://zhidao.baidu.com/link?url=8su4F16Et8Q0S3FmybwniJSI51Ms0AeVujcEXhyEaZh3u5LlOng5Xri_9zHsl7 ...

  4. MVC的验证 jquery.validate.unobtrusive

    jQuery validate 根据 asp.net MVC的验证提取简单快捷的验证方式(jquery.validate.unobtrusive.js) 2013-07-22 19:07 4568人阅 ...

  5. Decorator模式设计模式

    装饰者模式定义:动态地将责任附加到对象上. 若要扩展功能.装饰者提供了比继续更有弹性的替代方案. 简单定义:包装一个对象.以提供新的行为. 装饰者模式能够有效应对类爆炸问题. OO原则: 对扩展开放, ...

  6. ssis 到别的表查找临时变量值

    原文:ssis 到别的表查找临时变量值 etl过程过,往一个数据库表插入数据,插入的值往往需要到另外一个数据库读取.例如下面的客户跟踪,需要一个"项目ID",这个ID需要到另一个数 ...

  7. 使用Inno Setup 打包jdk、mysql、tomcat、webapp等为一个exe安装包

    之前一直都没涉及到打包安装方面的东西,都是另一个同事负责的,使用的工具(installshield)也比较高大上一点,可是后来他离职以后接受的同事也只能是在这个基础上做个简单的配置,然后打包,可是现在 ...

  8. [置顶] think in java interview-高级开发人员面试宝典(二)

    从现在开始,以样题的方式一一列出各种面试题以及点评,考虑到我在前文中说的,对于一些大型的外资型公司,你将会面临全程英语面试,因此我在文章中也会出现许多全英语样题. 这些题目来自于各个真实的公司,公司名 ...

  9. 安卓模拟器错误: Could not open

    在进行android模拟器測试的时候,出现下面错误,进度条满了之后就没反应了.图例如以下: 引起这个问题的可能原因有非常多: 原因一:由于我们採用的是绝对路径定位.也就是说在环境变量里面把路径写死了, ...

  10. Testin一日游实验室发布的行级APP质量报告:在那里拍携程双赢

    Testin实验室公布国庆出行旅途类APP质量报告:携程力压去哪儿夺冠 2014/09/28 · Testin · 实验室报告 一年一度的十一黄金周即将临近,旅游软件成为每外出行人手机必装软件.为此全 ...