📄 p2psendimage.cs
字号:
IsCancel=true;//取消为真
this.sendData(new sendFileInfo(0,0,0,null));//给对方发送“取消文件传输”消息
fileSendCancel(this,true);//触发“文件取消发送事件”(自己取消的)
}
}
private void linkSaveAs_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
System.Windows.Forms.SaveFileDialog fd=new SaveFileDialog ();
fd.Filter="文档(*"+ this.Extension +")|*"+ this.Extension;
fd.FileName=this.labFileName.Text;
if(fd.ShowDialog()==System.Windows.Forms.DialogResult.OK)
{
this.linkSaveAs.Visible=false;
this.labOr.Visible=false;
this.Refresh();
this.FileName=fd.FileName;
this.sendData (new sendFileInfo(1,0,0,null));//当用户单击接收文件时,发送消息给对方,要求对方开始发送文件数据块
}
}
private void linkReceive_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
this.sendData (new sendFileInfo(1,0,0,null));//当用户单击接收文件时,发送消息给对方,要求对方开始发送文件数据块
}
public void Listen()//UDP开始侦听来自外部的消息.
{
xx:
System.Random i =new Random();
int j= i.Next(2000,6000);
try
{
this.sockUDP1.Listen (j);
}
catch(Exception e)
{goto xx;}
}
private delegate void DataArrivaldelegate(byte[] Data, System.Net.IPAddress Ip, int Port);
private void DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port)
{
try
{
sendFileInfo msg=new LanMsg.Controls.ClassSerializers().DeSerializeBinary((new System.IO.MemoryStream(Data))) as sendFileInfo ;
serverIp=Ip;
this.serverPort=Port;
switch(msg.MsgInfoClass)
{
case 0://对方已经取消了文件传输
userCancelSendFile();//对方“取消了文件传输”
break;
case 1://对方发送“发送文件请求”过来,要求发送文件过去
ReadySendFile();//准备发送文件给对方
break;
case 2://对方发送文件数据过来,保存数据到文件
ReceivedFileBlock(msg);
break;
case 3://对方发送消息告诉已经收到上一次发送的文件数据块
ReceivedFileMsg(msg.pSendPos);
break;
}
}
catch(Exception e)
{}
}
private void ReceivedFileMsg(int CurrPos)//对方发送文件数据过来
{
this.pSendPos=CurrPos;
}
private void ReceivedFileBlock(sendFileInfo msg)//当对方发送文件数据块过来
{
if(this.pSendPos!=msg.pSendPos)return;
this.labelState.Text="正在接收文件...";
this.progressBar1.Maximum=(int)msg.fileSize;
this.progressBar1.Value=this.progressBar1.Value + msg.FileBlock.Length;
this.labelProgress.Text="("+ this.progressBar1.Value.ToString()+"/"+ this.progressBar1.Maximum.ToString()+")";//显示文件传输(接收)进度
// this.xpProgressBar1.PositionMax=(int)msg.fileSize;
// this.xpProgressBar1.Position=this.progressBar1.Value + msg.FileBlock.Length;
// this.xpProgressBar1.Text="("+ this.progressBar1.Value.ToString()+"/"+ this.progressBar1.Maximum.ToString()+")";
this.pSendPos=(msg.pSendPos + msg.FileBlock.Length);//记录文件发送方当前发送文件块的起点位置
if(!IsSendState)//如果当前没有接收文件,则打开文件并保存数据块,如果当前文件是处于接收状态,则文件已经打开,不需要再执行打开操作
fStream =new System.IO.FileStream(FileName , FileMode.Create, FileAccess.Write, FileShare.Read);
fStream.Write(msg.FileBlock,0,msg.FileBlock.Length );//将收到的文件块存于文件中
fStream.Flush();
IsSendState=true;//标识当前正在传输文件
this.sendData(new sendFileInfo(3,0,this.progressBar1.Value,null));//发送消息通知文件发送方已经收到数据并保存,可以继续发送下一文件块数据
if(this.progressBar1.Value>=this.FileSize)//如果文件传输已经完成
{
IsSendState=false;//文件传输状态设置为否,表示文件没有在传输中
this.sendOver=true;//文件发送完成值设为真
fStream.Close(); //关闭打开的文件
this.sockUDP1.CloseSock();
IsCancel=true;//取消为真
fileSendEnd(this,false);//触发文件传输结束事件
}
}
private void ReadySendFile()//准备发送文件给对方
{
System.IO.FileInfo f=new FileInfo(this.FileName);
if(!f.Exists)return;
this.FileSize=f.Length;
System.Threading.Thread RThread = new System.Threading.Thread( new System.Threading.ThreadStart(sendFileData));
RThread.Start(); //开始发送文件
}
private void sendFileData()//发送文件
{
try
{
this.labelState.Text="正在发送文件...";
this.progressBar1.Maximum=Convert.ToInt32(this.FileSize) ;
// this.xpProgressBar1.PositionMax=Convert.ToInt32(this.FileSize);
byte[] buffer = new byte[buf];
int i=0;//记录当前读取文件所获得的字节数
int currSendPos=0;//设置当前发送的文件块的终点位置
this.fStream =new System.IO.FileStream(this.FileName , FileMode.Open, FileAccess.Read, FileShare.Read);//打开文件,准备发送数据
this.IsSendState=true;//设置文件发送状态为真,表示文件正在发送中
while(currSendPos<this.FileSize && !userCancelSend)//当前已发送文件的终点位置小于文件尺寸并且对方没有取消文件传输时执行发送文件下一区块数据
{
if(currSendPos==this.pSendPos)//当对方收到的文件块终点位置等于前一次发送的文件块终点位置时才发送一下区块数据,确保文件发送的完整性
{
if((currSendPos+this.buf)>this.FileSize)//如果上次发送的数据位置加上缓冲区最大数BUF大于文件尺寸,则只发送最后一部分数据
{
buffer = new byte[Convert.ToInt32(this.FileSize-currSendPos)];
}
i=fStream.Read(buffer,0,buffer.Length);//将要发送的文件块数据存入发送缓冲区
if(i!=0)//如果缓冲区中的数据不为空,则将数据发送给对方
{
this.sendData(new sendFileInfo(2,this.FileSize,currSendPos,buffer));//发送已读取的文件数据给对方
currSendPos +=i;//上一次发送终点位置更改为这一次发送的终点位置
this.progressBar1.Value= currSendPos;//更新进度条进度显示
this.labelProgress.Text="("+ this.progressBar1.Value.ToString()+"/"+ this.progressBar1.Maximum.ToString()+")";
// this.xpProgressBar1.Position =currSendPos;
// this.xpProgressBar1.Text ="("+ this.progressBar1.Value.ToString()+"/"+ this.progressBar1.Maximum.ToString()+")";
}
}
}
//程序执行到这里表示文件已经结束或是对方取消了文件传输
fStream.Close(); //关闭打开的文件
this.sockUDP1.CloseSock();//关闭通信端口
IsSendState=false;//文件传输状态设置为否,表示文件没有在传输中
IsCancel=true;//取消为真
if(!userCancelSend)//如果对方没有取消文件传输而文件是正常传输结束,则标识
{
this.sendOver=true;
fileSendEnd(this,true) ;//触发文件正常传输结束事件
}
}
catch(Exception e)
{
//MessageBox.Show(e.Message );
}
}
private void userCancelSendFile()//当对方“取消了文件传输”
{
IsCancel=true;//取消为真
fileSendCancel(this,false);//触发“文件取消发送事件”(对方取消的)
}
private void sockUDP1_DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port)
{
DataArrivaldelegate outdelegate = new DataArrivaldelegate( DataArrival);
this.BeginInvoke (outdelegate, new object[]{ Data,Ip,Port});
}
private void sendData(sendFileInfo fInfo)
{
this.sockUDP1.Send(serverIp,this.serverPort,new Controls.ClassSerializers().SerializeBinary(fInfo).ToArray());
}
public void SendData(System.Net.IPAddress Ip,int Port,byte[] MsgContent)
{
this.sockUDP1.Send (Ip,Port,MsgContent);
}
private void timer1_Tick(object sender, System.EventArgs e)//保持UDP端口在外网上的映射
{
this.sockUDP1.Send(this.serverIp ,this.serverPort,new Controls.ClassSerializers().SerializeBinary(new sendFileInfo(100,0,0,null)).ToArray());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -