C# 由long定义的数组大小导致算术溢出
我正在使用套接字,并将PDF、文档等小文件传输到服务器。在服务器端,我读取套接字数据并解析出发送的文件大小 我使用的是流,所以文件大小是长的。问题是我的缓冲区是1024,所以我发送的最后一个数据包很少是1024,这意味着我将得到一个数据量为741kbs的数据包,而缓冲区的其余部分则充满了0 为了解决破坏最终输出的问题,我计算了文件大小的差异,然后创建一个新的缓冲区,只复制我需要的内容,留下垃圾。它在我的PC上运行得很好,但它会在我要运行服务器的VMware上引发算术溢出。我认为它使用的是比我旧的.Net版本,尽管我在开发PC上的目标是4.5 这就是问题中的代码。我试过使用检查和未检查的符号,所有的东西。有什么建议吗C# 由long定义的数组大小导致算术溢出,c#,.net,arrays,sockets,bytearray,C#,.net,Arrays,Sockets,Bytearray,我正在使用套接字,并将PDF、文档等小文件传输到服务器。在服务器端,我读取套接字数据并解析出发送的文件大小 我使用的是流,所以文件大小是长的。问题是我的缓冲区是1024,所以我发送的最后一个数据包很少是1024,这意味着我将得到一个数据量为741kbs的数据包,而缓冲区的其余部分则充满了0 为了解决破坏最终输出的问题,我计算了文件大小的差异,然后创建一个新的缓冲区,只复制我需要的内容,留下垃圾。它在我的PC上运行得很好,但它会在我要运行服务器的VMware上引发算术溢出。我认为它使用的是比我旧的
Int64 resizeTo = (int)(packet.payloadSize - packet.ms.Length);
byte[] endByte = new byte[(int)resizeTo];
Array.Copy(packet.buff, 0, endByte, 0, endByte.Length);
编辑:正在讨论的方法
public void ReadCallback(IAsyncResult ar)
{
try
{
PacketInfo packet = (PacketInfo)ar.AsyncState;
Socket handler = packet.socket;
int bytesRead = handler.EndReceive(ar);
string remotePoint = handler.RemoteEndPoint.ToString();
if (bytesRead > 0)
{
string peek = Encoding.UTF8.GetString( packet.buff );
if ( peek.Contains(hStart ) )
{
// file size
byte[] fSize = new byte[8];
Array.Copy(packet.buff, 8, fSize, 0, fSize.Length);
packet.payloadSize = BitConverter.ToInt64(fSize, 0);
// File Name and User ID
string[] s = peek.Split('#');
foreach (string t in s)
{
if (t.Contains(@"\"))
packet.fileName = t;
if (t.Trim().Length == 7)
packet.ADID = t;
}
}
else if ( peek.Contains(dEnd ) )
{
// Trim up last bytes of info, buffers set to1024 but if the last byte wasnt that big it gets padded with 0s by the socket
Int64 resizeTo = (int)(packet.payloadSize - packet.ms.Length);
byte[] endByte = new byte[(int)resizeTo];
Array.Copy(packet.buff, 0, endByte, 0, endByte.Length);
packet.ms.Write(endByte, 0, endByte.Length);
long payloadSize = packet.payloadSize;
long streamSize = packet.ms.Length;
// verify file size, reject if it doesn't match checksum
if ( payloadSize == streamSize )
{
// Handle completed file transfer
FileTransferCompleted(packet.ms);
packet.socket.Send(Encoding.UTF8.GetBytes(sAck));
UpdateStatus("Payload should be: " + payloadSize + " payload was: " + streamSize + " for: " + remotePoint + "\n");
UpdateStatus("Sending acknowledgement and closing socket to: " + remotePoint + "\n");
packet.socket.Close();
packet = null;
return;
}
packet.socket.Send(Encoding.UTF8.GetBytes(rAck));
packet.ms.Position = 0;
UpdateStatus("Payload should be: " + packet.payloadSize + " payload was: " + packet.ms.Length + " for: " + remotePoint + "\n");
UpdateStatus("Sending request for retransfer to: " + remotePoint + "\n");
}
else
{
packet.ms.Write(packet.buff, 0, packet.buff.Length);
//UpdateStatus("Receiving data from: " + remotePoint + "\n"); // only for debug
}
handler.BeginReceive(packet.buff, 0, packet.buff.Length,
SocketFlags.None,
new AsyncCallback(ReadCallback), packet);
//UpdateStatus("Checking for data from: " + remotePoint + "\n"); // only for debug
}
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
}
public class PacketInfo
{
public Socket socket = null;
public const int buffSize = 1024;
public byte[] buff = new byte[buffSize];
public MemoryStream ms = new MemoryStream();
public long payloadSize;
public string fileName = null;
public string ADID = null;
}
编辑服务器代码的其余部分
public class Server
{
// socket protocol messages
const string hStart = "<<head>>"; // header start
const string dEnd = "<<end>>"; // data end
const string sAck = "<<success>>"; // received
const string rAck = "<<resend>>"; // received, didn't match checksum, resend
int _port;
int _maxConnections;
// Internal event
ManualResetEvent allDone = new ManualResetEvent(false);
// Public update event for status updates
public delegate void StatusUpdateHandler(object sender, StatusUpdateEvent e);
public event StatusUpdateHandler onStatusUpdate;
// public event for file completion status
public delegate void FileTransferHandler(object sender, FileTransferComplete e);
public event FileTransferHandler onFileTransferComplete;
public int Port {
get { return _port; }
}
public int MaxConnections {
get { return _maxConnections; }
}
public Server( int port, int maxConnections )
{
this._port = port;
this._maxConnections = maxConnections;
}
void UpdateStatus(string status)
{
if (onStatusUpdate == null)
{
Debug.WriteLine("NULL");
return;
}
StatusUpdateEvent args = new StatusUpdateEvent(status);
onStatusUpdate(this, args);
}
void FileTransferCompleted( object payload )
{
if ( onFileTransferComplete == null )
{
Debug.WriteLine("Null File Transfer Completed Event");
return;
}
FileTransferComplete args = new FileTransferComplete(payload);
onFileTransferComplete(this, args);
}
public void SpinUp()
{
IPHostEntry ipHost = Dns.GetHostEntry("");
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, _port);
SocketPermission permission = new SocketPermission(
NetworkAccess.Accept,
TransportType.Tcp,
"",
SocketPermission.AllPorts
);
permission.Demand();
Socket sListener = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener.Bind(ipEndPoint);
sListener.Listen(_maxConnections);
while (true)
{
allDone.Reset();
UpdateStatus("Waiting for connections on port " + _port + ":\n");
Debug.WriteLine("Waiting for connections.");
sListener.BeginAccept(
new AsyncCallback(AcceptCallback),
sListener );
allDone.WaitOne();
}
}
public void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
try
{
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
UpdateStatus("Connection received from: " + handler.RemoteEndPoint + "\n" );
handler .NoDelay = false;
PacketInfo packet = new PacketInfo();
packet.socket = handler;
handler .BeginReceive(
packet.buff,
0,
packet.buff.Length,
SocketFlags.None,
new AsyncCallback(ReadCallback),
packet
);
}
catch ( OverflowException overflow )
{
MessageBox.Show(overflow.ToString());
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
公共类服务器
{
//套接字协议消息
常量字符串hStart=“”;//头开始
常量字符串dEnd=”“;//数据结束
const string sAck=“;//已收到
const string rAck=”“;//已接收,与校验和不匹配,请重新发送
国际港口;
int_最大连接;
//内部事件
ManualResetEvent allDone=新的ManualResetEvent(错误);
//状态更新的公共更新事件
公共委托void StatusUpdateHandler(对象发送方,StatusUpdateEvent e);
公共事件状态更新Handler onStatusUpdate;
//文件完成状态的公共事件
公共委托无效FileTransferHandler(对象发送方、FileTransfere);
公共事件FileTransferHandler onFileTransferComplete;
公共int端口{
获取{return\u port;}
}
公共int MaxConnections{
获取{return\u maxConnections;}
}
公共服务器(int端口、int maxConnections)
{
这个。_port=port;
这是.\u maxConnections=maxConnections;
}
无效更新状态(字符串状态)
{
if(onStatusUpdate==null)
{
Debug.WriteLine(“空”);
返回;
}
StatusUpdateEvent args=新的StatusUpdateEvent(状态);
onStatusUpdate(此参数为args);
}
void FileTransferCompleted(对象负载)
{
if(onfiletTransferComplete==null)
{
WriteLine(“空文件传输完成事件”);
返回;
}
FileTransferComplete args=新的FileTransferComplete(有效负载);
onfilettransfercomplete(此参数为args);
}
公共空间螺旋上升()
{
IPHostEntry ipHost=Dns.GetHostEntry(“”);
IPAddress ipAddr=ipHost.AddressList[0];
IPEndPoint IPEndPoint=新IPEndPoint(ipAddr,_端口);
SocketPermission=新建SocketPermission(
NetworkAccess.Accept,
TransportType.Tcp,
"",
SocketPermission.AllPorts
);
permission.Demand();
插座滑动器=新插座(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
滑动器。绑定(i端点);
sListener.Listen(\u maxConnections);
while(true)
{
全部完成。重置();
UpdateStatus(“正在端口上等待连接”+_port+“:\n”);
Debug.WriteLine(“等待连接”);
开始接受(
新建异步回调(AcceptCallback),
斯莱斯腾纳);
全部完成。WaitOne();
}
}
公共无效接受回调(IAsyncResult ar)
{
allDone.Set();
尝试
{
套接字侦听器=(套接字)ar.AsyncState;
套接字处理程序=listener.EndAccept(ar);
UpdateStatus(“从以下地址接收的连接:“+handler.RemoteEndPoint+”\n”);
handler.NoDelay=false;
PacketInfo packet=新的PacketInfo();
packet.socket=处理程序;
handler.BeginReceive(
buff,
0,
packet.buff.Length,
SocketFlags,没有,
新建异步回调(ReadCallback),
小包裹
);
}
捕获(溢出异常溢出)
{
Show(overflow.ToString());
}
捕获(异常exc)
{
Show(exc.ToString());
}
}
客户端代码
namespace Client
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
const string hStart = "<<head>>"; // header start
const string dEnd = "<<end>>"; // data end
const string sAck = "<<success>>"; // received
const string rAck = "<<resend>>"; // resend
BindingList<string> connections = new BindingList<string>();
public List<byte[]> buildTransfer( FileStream fs )
{
List<byte[]> packets = new List<byte[]>();
using ( fs )
{
using ( MemoryStream ms = new MemoryStream() )
{
fs.CopyTo(ms);
ms.Position = 0;
ms.Flush();
byte[] header = genHeader( ms.Length, fs.Name, Environment.UserName );
packets.Add(header);
int incomingOffset = 0;
while(incomingOffset < ms.ToArray().Length)
{
byte[] buffer = new byte[1024];
int length =
Math.Min(buffer.Length, ms.ToArray().Length - incomingOffset);
if ( length < buffer.Length )
{
buffer = new byte[length + dEnd.Length];
byte[] endblock = Encoding.UTF8.GetBytes(dEnd);
Buffer.BlockCopy(ms.ToArray(), incomingOffset,
buffer, 0,
length);
Buffer.BlockCopy(endblock, 0, buffer, length, endblock.Length);
packets.Add(buffer);
return packets;
}
Buffer.BlockCopy(ms.ToArray(), incomingOffset,
buffer, 0,
length);
incomingOffset += length;
packets.Add(buffer);
}
}
}
byte[] footer = new byte[1024];
footer[0] = Encoding.UTF8.GetBytes(dEnd)[0];
packets.Add(footer);
return packets;
}
byte[] genHeader( long fileSize, string fileName, string ADID )
{
byte[] header = new byte[1024];
byte[] adid = Encoding.UTF8.GetBytes(Environment.UserName);
byte[] fName = Encoding.UTF8.GetBytes(fileName);
byte[] start = Encoding.UTF8.GetBytes(hStart);
byte pad = Encoding.UTF8.GetBytes("#")[0];
int x = 0;
foreach( byte b in start )
{
header[x] = b;
x++;
}
foreach( byte b in BitConverter.GetBytes(fileSize) )
{
header[x] = b;
x++;
}
header[x] = pad;
x++;
foreach( byte b in fName )
{
header[x] = b;
x++;
}
header[x] = pad;
x++;
foreach( byte b in adid )
{
header[x] = b;
x++;
}
header[x] = pad;
x++;
return header;
}
public MainForm()
{
InitializeComponent();
dataGridView1.DataSource = connections;
for( int x = 0; x < 1; x++ )
{
Thread nt = new Thread(connect);
nt.Start();
Thread.Sleep(1000);
}
//connect();
}
void connect()
{
byte[] bytes = new byte[1024];
Socket senderSock;
try
{
// Create one SocketPermission for socket access restrictions
SocketPermission permission = new SocketPermission(
NetworkAccess.Connect, // Connection permission
TransportType.Tcp, // Defines transport types
"", // Gets the IP addresses
SocketPermission.AllPorts // All ports
);
// Ensures the code to have permission to access a Socket
permission.Demand();
// Resolves a host name to an IPHostEntry instance
IPHostEntry ipHost = Dns.GetHostEntry("");
// Gets first IP address associated with a localhost
IPAddress ipAddr = ipHost.AddressList[0];
// Creates a network endpoint
IPEndPoint ipEndPoint = CreateIPEndPoint("10.212.98.71:4510");
//IPEndPoint ipEndPoint = new IPEndPoint(ipHost.AddressList[0], 4510);
// Create one Socket object to setup Tcp connection
senderSock = new Socket(
ipAddr.AddressFamily,// Specifies the addressing scheme
SocketType.Stream, // The type of socket
ProtocolType.Tcp // Specifies the protocols
);
senderSock.NoDelay = false; // Using the Nagle algorithm
// Establishes a connection to a remote host
senderSock.Connect(ipEndPoint);
connections.Add(senderSock.LocalEndPoint.ToString());
List<byte[]> toSend = new List<byte[]>();
using( FileStream fs = new FileStream(@"C:\Users\jdy5tnh\Downloads\b3.pdf", FileMode.Open) )
{
toSend = buildTransfer(fs);
}
while( true )
{
foreach( byte[] b in toSend )
senderSock.Send(b);
byte[] buffer = new byte[1024];
senderSock.Receive(buffer);
if (Encoding.UTF8.GetString(buffer).Contains(sAck ) )
{
senderSock.Close();
senderSock.Dispose();
return;
}
else
{
MessageBox.Show(Encoding.UTF8.GetString(buffer));
}
}
} catch (Exception exc) {
MessageBox.Show(exc.ToString());
}
}
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length != 2)
throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (!IPAddress.TryParse(ep[0], out ip)) {
throw new FormatException("Invalid ip-adress");
}
int port;
if (!int.TryParse(ep[1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port)) {
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
}
}
命名空间客户端
{
///
///主窗体的描述。
///
公共部分类主窗体:窗体
{
常量字符串hStart=“”;//头开始
常量字符串dEnd=”“;//数据结束
const string sAck=“;//已收到
const string rAck=”“;//重新发送
BindingList连接=新建BindingList();
公共列表buildTransfer(FileStream fs)
{
列表数据包=新列表();
使用(fs)
{
使用(MemoryStream ms=new MemoryStream())
{
财政司司长(ms);
ms.Position=0;
弗拉什女士();
byte[]header=genHeader(ms.Length、fs.Name、Environment.UserName);
数据包添加(报头);
int incomingOffset=0;
while(incomingOffsetint result = peek.IndexOf(dEnd, StringComparison.Ordinal);
byte[] endByte = new byte[result];