使用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 ...
随机推荐
- thinkphp5.0 中使用第三方无命名空间的类库
ThinkPHP5建议所有的扩展类库都使用命名空间定义,如果你的类库没有使用命名空间,则不支持自动加载,必须使用Loader::import方法先导入文件后才能使用. 首先要在文件头部使用loader ...
- 使用CALayer实现图像镜面效果
在iOS中,可以使用QuartzCore.framework基于CALayer做一些图像效果,不清楚CALayer,请先看这篇. 在这里我们给图像做一个简单的镜面反射效果,要学习一些图像变化的知识,首 ...
- Razor语法(四)
1. @代表开始一个Razor代码块,Razor会自动匹配代码中的花括号,比如@if(p.Active){<li>@p.Name</li>} 2. @{code}标识一个Raz ...
- angular 的进一步深入理解
早上同事问我个问题,angular 的表单验证有没有啥第三方库可以用? 这个问题,我想了下,之前我做的表单验证好像也没用到第三方的库来验证,直接用angular 内置的 directive 就可以搞定 ...
- HDU2189 悼念512汶川大地震遇难同胞——来生一起走 【母函数】
悼念512汶川大地震遇难同胞--来生一起走 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- iOS 8 Share Extension Safari URL Example(在iOS中分享url的样例)
ios8 的Extension给我们提供了非常多奇妙的功能.以后分享内容再也不用进入app了,让我们的手机更安全,以下我们以在safari 浏览器中分享一个web url 来讲述Share Exten ...
- LeetCode Add Binary |My Solution
Given two binary strings, return their sum (also a binary string). For example, a = "11" b ...
- MP3中设置播放顺序的软件《闪存式MP3伴侣》
给姥爷买了一个插卡音箱,里面拷贝了几百段评书,每一段评书都是一个mp3文件,虽然插卡音箱会自动一个文件一个文件自动播放,可是比较郁闷的是评书的播放顺序完全是乱的,毫无规律可寻,本来我的mp3文件的文件 ...
- BitConverter.GetBytes(int)和BitConverter.ToString 方法 (Byte[])
BitConverter.ToString 方法 (Byte[]) 网址:https://msdn.microsoft.com/zh-cn/library/3a733s97(v=vs.110).asp ...
- vue - dist
描述:打包后准备上线的文件(需要服务器环境才能运行!!!)