使用Net.Sockets.TcpListener和Net.Sockets.TcpClient进行图片传输时怎样精确控制接收缓存数组大小
<span style="font-size:18px;">在dotnet平台Net.Sockets.TcpListener和Net.Sockets.TcpClient已经为我们封装了全部Socket关于tcp部分,操作也更为简单,面向数据流。使用TcpClient的GetStream方法获取数据流后能够方便的对数据流进行读写操作,就如同本地磁盘的文件读写一样,使得程序猿在设计程序时更为便捷简单。</span>
但假设你使用过这两个对象进行传输数据的时候,你会发现问题也随之而来——GetStream获取的数据流是一个永无止境的Stream,你无法获取它的详细长度。
来看一下微软MSDN关于这两个对象的例程:
Shared Sub Connect(server As [String], message As [String])
Try
' Create a TcpClient.
' Note, for this client to work you need to have a TcpServer
' connected to the same address as specified by the server, port
' combination.
Dim port As Int32 = 13000
Dim client As New TcpClient(server, port) ' Translate the passed message into ASCII and store it as a Byte array.
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message) ' Get a client stream for reading and writing.
' Stream stream = client.GetStream();
Dim stream As NetworkStream = client.GetStream() ' Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length) Console.WriteLine("Sent: {0}", message) ' Receive the TcpServer.response.
' Buffer to store the response bytes.
data = New [Byte](256) {} ' String to store the response ASCII representation.
Dim responseData As [String] = [String].Empty ' Read the first batch of the TcpServer response bytes.
Dim bytes As Int32 = stream.Read(data, 0, data.Length)
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
Console.WriteLine("Received: {0}", responseData) ' Close everything.
stream.Close()
client.Close()
Catch e As ArgumentNullException
Console.WriteLine("ArgumentNullException: {0}", e)
Catch e As SocketException
Console.WriteLine("SocketException: {0}", e)
End Try Console.WriteLine(ControlChars.Cr + " Press Enter to continue...")
Console.Read()
End Sub 'Connect
你不得不去指定一个固定尺寸的缓冲区来接收数据,假设实际发送的数据超出了这个长度,你可能无法接收到所有完整的数据,而假设发送的数据少于缓冲区的大小,那么非常显然你的内存会比别人消耗的更快。更为严重的时。假设你要发送一副图片,图片容量可能依据内容的不同而各有千秋,容量也不止256Byte这么小,该怎样精确控制缓冲区呢?
事实上我们能够非常easy的解决问题,就像非常多文件格式所做的事情一样,我们能够在Stream的前几个字节写入实际有效数据的长度。然后依据这个长度来分配内存。再读取内容,我所做的client与server之间传递屏幕的源码例如以下:
'----------------client----------------
<pre name="code" class="vb">Public Class Form1
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim tcpc As New Net.Sockets.TcpClient
Dim slens(7) As Byte
Try
tcpc.Connect("127.0.0.1", 2099)
If tcpc.Connected Then
For i = 0 To 7
slens(i) = tcpc.GetStream.ReadByte
Next
Dim buf(BitConverter.ToUInt64(slens, 0)) As Byte
Me.Text = buf.Length
tcpc.GetStream.Read(buf, 0, buf.Length)
Dim mem As New IO.MemoryStream(buf)
Dim bmp As New Bitmap(mem)
Me.PictureBox1.Image = bmp
tcpc.Close()
End If
Catch ex As Exception
Finally
tcpc.Close()
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
'------------server----------------
Public Class Form1
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim tcps As New Net.Sockets.TcpListener(2099)
tcps.Start()
While True
Dim slen As UInt64
Dim slens(7) As Byte
Dim tcpc As Net.Sockets.TcpClient
tcpc = tcps.AcceptTcpClient
'创建图片
Dim bmp As New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
bmp.SetResolution(1, 1)
Dim gph As Graphics = Graphics.FromImage(bmp)
gph.CopyFromScreen(New Point(0, 0), New Point(0, 0), bmp.Size)
gph.Flush()
'存入内存
Dim mem As New IO.MemoryStream
bmp.Save(mem, Drawing.Imaging.ImageFormat.Tiff)
'文件长度
slen = mem.Length
slens = BitConverter.GetBytes(slen)
'发送长度
For i = 0 To 7
tcpc.GetStream.WriteByte(slens(i))
Next
'发送内容
tcpc.GetStream.Write(mem.ToArray, 0, mem.Length)
tcpc.Close()
End While
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
End Class
使用Net.Sockets.TcpListener和Net.Sockets.TcpClient进行图片传输时怎样精确控制接收缓存数组大小的更多相关文章
- C# Socket TcpClient 无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接。。
开始的代码: byte[] data = Encoding.UTF8.GetBytes(sInfo); tcpns.Write(data, 0,1024); 修改 ...
- TcpClient
public class TcpClientSession { protected TcpClient Client { get; set; } /// <summary> /// 远程地 ...
- records.config文件参数解释
# Process Records Config File # # <RECORD-TYPE> <NAME> <TYPE> <VALUE (till end ...
- TCP的发送系列 — 发送缓存的管理(一)
主要内容:TCP发送缓存的初始化.动态调整.申请和释放. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 数据结构 TCP对发送缓存的管理是在两个层面上进 ...
- records.config中文详解
转载:http://www.safecdn.cn/cdn/2018/12/records-config-zh/106.html records.config参数的一些备注 CONFIG proxy.c ...
- TCP 接收窗口自动调节
https://technet.microsoft.com/zh-cn/magazine/2007.01.cableguy.aspx 欢迎来到 TechNet 杂志“网络专家”的第一部分.TechNe ...
- wp socket tcp链接
using System; using System.Net; /// <summary> /// 客户端通过TCP/IP连接服务端的方法,包含连接,发送数据,接收数据功能 /// < ...
- Linux 内核参数说明
转载自: https://www.cnblogs.com/tolimit/p/5065761.html 因个人能力有限,不能保证所有描述都正确,还请大家集思广益,有错误的地方欢迎大家留言指正,同时也欢 ...
- Nginx之核心结构体ngx_cycle_t
1. ngx_listening_t 结构体 ngx_cycle_t 对象中有一个动态数组成员叫做 listening,它的每个数组元素都是 ngx_listening_t 结构体,而每个 ngx_l ...
随机推荐
- scrapy-splash抓取动态数据例子三
一.介绍 本例子用scrapy-splash抓取今日头条网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...
- [ES6] 09. Destructuring Assignment -- 2
Read More: http://es6.ruanyifeng.com/#docs/destructuring Array “模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值: Ex ...
- XP系统如何把桌面图标变大
右击桌面,属性,外观,高级,在项目里面找到图标,大小改为你喜欢的样式. 我测试的结果是:图标大小改为42,字体大小改为8,图标垂直间距改为100,水平间距改为54效果不错.
- PageRank学习
喜欢手写学习,记忆深刻(字丑勿喷!). 计算过程的代码如下: public class PageRank { private static double m[][]={ { 0 , 0.5 , 1 , ...
- Git原始笔记
.dir .mkdir lxit .cd lxit .git init(git仓库不要动!!! 除非用命令动它里面的文件,新添加的可以动) .ls .pwd Config: git config -- ...
- 不吐不快之EJB演练——开篇概述
EJB(Enterprise Java Bean)是J2EE规范的重要核心,它是一个用户分布式业务应用的标准服务端组件模型,它是一种能够高速开发大规模企业应用的组件体系结构.上面这样官方的解释可能对于 ...
- win7 linux双系统删除linux
本文内容收集自互联网,共两篇,中间以“分界线”进行分割. linux的卸载 一.win7与linux都使用grub来引导 卸载:不能直接删除ubuntu分区,这样会造成win7也启动不了 正确方法: ...
- docker高级应用之cpu与内存资源限制(转)
时间:2015-06-09 14:01:52 阅读:1581 评论:0 收藏:0 [点我收藏+] 标签:docker资源限制 docker cpu限制 ...
- Cacti监控MySQL实现过程中碰到的问题解汇总
前言:cacti监控mysql服务器的大概50张graphs都弄出来了,也出图了,当中遇到一些问题,印象比較深刻的记录例如以下: (一):加入io监控 点击Create Graphs for this ...
- 理解lvalue和rvalue
今天看C++模板的资料,里面说到lvalue,rvalue的问题,这个问题以前也看到过,也查过相关资料,但是没有考虑得很深,只知道rvalue不能取地址,不能赋值等等一些规则.今天则突然有了更深层次的 ...