使用C#进行点对点通讯和文件传输
发送部分:
发送咱们使用了多线程,可以同时进行多个任务,比如发送文件、发送文本等,互不影响:
发送文本方法:
private void StartSendText(string strHost,int iPort,string strInfo)
{
SendText stText = new SendText(strHost,iPort,strInfo,new CommunClass.OnSend(OnSendDrawProgress)) ;
StartThread(new ThreadStart(stText.Send)) ;
}
下面是他调用用到的一些方法:
开始一个线程
private void StartThread(ThreadStart target)
{
Thread doStep = new Thread(target) ;
doStep.IsBackground = true ;
doStep.Start() ;
}
发送一部分(本文设置的是1024字节)成功后的回调方法
public void OnSendDrawProgress(int iTotal,int iSending)
{
if (iTotal != pbMain.Maximum)
pbMain.Maximum = iTotal ;
pbMain.Value = iSending ;
}
因为使用的是线程,所以发送文本使用的是一个发送文本类的方法,该类如下:
public class SendText
{
private string Host ;
private int Port ;
private string Info ;
private CommunClass.OnSend onsend ;
public SendText(string strHost,int iPort,string strInfo,
CommunClass.OnSend onSend)
{
Host = strHost ;
Port = iPort ;
Info = strInfo ;
onsend = onSend ;
}
public void Send()
{
Socket s = null ;
try
{
s = CommunClass.ConnectToServer(Host,Port) ;
CommunClass.WriteCommandToSocket(s,"SENDTEXT") ;
CommunClass.WriteCommandDescToSocket(s,"") ;
CommunClass.WriteDynamicTextToSocket(s,Info,onsend) ;
}
catch (Exception e)
{
MessageBox.Show(e.Message) ;
}
finally
{
if (s != null)
s.Close() ;
}
}
}//end class
这样就可以使用一个线程发送文本了。
发送文件的方法也类似:
private void StartSendFile(string strHost,int iPort,string strFile)
{
SendFile sfFile = new SendFile(strHost,iPort,strFile,this.pbMain) ;
pbMain.Value = 0 ;
StartThread(new ThreadStart(sfFile.Send)) ;
}
发送文件的类:
public class SendFile
{
private string Host ;
private int Port ;
private string FileToSend ;
private ProgressBar pbar;
public SendFile(string strHost,int iPort,string strFile,ProgressBar pbMain)
{
Host = strHost ;
Port = iPort ;
FileToSend = strFile ;
pbar = pbMain ;
}
public void Send()
{
Socket s = null ;
try
{
s = CommunClass.ConnectToServer(Host,Port) ;
CommunClass.WriteCommandToSocket(s,"SENDFILE") ;
CommunClass.WriteCommandDescToSocket(s,"") ;
CommunClass.WriteFileToSocket(s,FileToSend,new CommunClass.OnSend(OnSendDrawProgress)) ;
}
catch (Exception e)
{
MessageBox.Show(e.Message) ;
}
finally
{
if (s != null)
s.Close() ;
}
}
public void OnSendDrawProgress(int iTotal,int iSending)
{
if (iTotal != pbar.Maximum)
pbar.Maximum = iTotal ;
pbar.Value = iSending ;
}
}//end class
当然,你发送一个命令让服务器端启动一个程序(靠,这不成木马了吗?)也可以:
俺这里只给出一部分代码,其余的您自己可以发挥以下:
public class ExeCuteFile
{
private string Host ;
private int Port ;
private string FileName ;
private string cmdParam ;
public ExeCuteFile(string strHost,int iPort,string strFileName,string strCmdParam)
{
Host = strHost ;
Port = iPort ;
FileName = strFileName ;
cmdParam = strCmdParam ;
}
public void Send()
{
Socket s = null ;
try
{
s = CommunClass.ConnectToServer(Host,Port) ;
CommunClass.WriteCommandToSocket(s,"EXECUTEFILE") ;
CommunClass.WriteCommandDescToSocket(s,FileName) ;
CommunClass.WriteDynamicTextToSocket(s,"",null) ;
MessageBox.Show(CommunClass.ReadDynamicTextFromSocket(s)) ;
}
catch (Exception e)
{
MessageBox.Show(e.Message) ;
}
finally
{
if (s != null)
s.Close() ;
}
}
}
下面是服务器端接受信息的代码:
创建监听:
/// <summary>
/// 再给定的主机和端口上创建监听程序
/// </summary>
/// <param name="strAddress"></param>
/// <param name="iPort"></param>
private void BuildingServer(string strAddress,int iPort)
{
IPAddress ipAddress = Dns.Resolve(strAddress).AddressList[0];
try
{
listener = new TcpListener(ipAddress, iPort);
}
catch ( Exception e)
{
AddInfo(e.Message) ;
}
}
<b>开始监听:</b>
/// <summary>
/// 开始监听
/// </summary>
private void StartListen()
{
bool done = false;
listener.Start();
while (!done)
{
Socket s = listener.AcceptSocket() ;
if(s != null)
{
DealWithSocket dws = new DealWithSocket(s,this.tbLog) ;
StartThread(new ThreadStart(dws.DealWith)) ;
}
}
}
private void StartThread(ThreadStart target)
{
Thread doStep = new Thread(target) ;
doStep.IsBackground = true ;
doStep.Start() ;
}
开始监听后,对于每一个监听到的客户端的连接都用一个单独的线程来处理,处理通过类DealWithSocket来完成,下面是类代码:
public class DealWithSocket
{
private Socket s = null ;
private TextBox tbLog = null ;
public DealWithSocket(Socket newSocket,TextBox tbInfo)
{
s = newSocket ;
tbLog = tbInfo ;
}
public void DealWith()
{
string strCmd = CommunClass.ReadCommandFromSocket(s) ;
string strDesc = CommunClass.ReadCommandDescFromSocket(s) ;
AddInfo(strCmd) ;
switch(strCmd)
{
case "SENDFILE" :
CommunClass.ReadDynamicFileFromSocket(s,"e:\\rrr.txt") ;
break ;
case "EXECUTEFILE" :
string strParam = CommunClass.ReadDynamicTextFromSocket(s) ;
string strResult = ExeCuteFile(strDesc,strParam) ;
CommunClass.WriteDynamicTextToSocket(s,strResult,null) ;
break ;
default:
string strDetail = CommunClass.ReadDynamicTextFromSocket(s) ;
AddInfo(strDetail) ;
break ;
}
try
{
s.Close() ;
}
catch (Exception e)
{
AddInfo(e.Message) ;
}
}
private void AddInfo(string strInfo)
{
string Info = DateTime.Now.ToLongTimeString() + " "+ strInfo +"\r\n" ;
tbLog.Text += Info ;
tbLog.Refresh() ;
}
private string ExeCuteFile(string strFileName,string strCmdParam)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process() ;
proc.StartInfo.FileName = strFileName ;
proc.StartInfo.Arguments = strCmdParam ;
try
{
proc.Start() ;
return "OK" ;
}
catch(Exception err)
{
return err.Message ;
}
}
}//end class
发送咱们使用了多线程,可以同时进行多个任务,比如发送文件、发送文本等,互不影响:
发送文本方法:
private void StartSendText(string strHost,int iPort,string strInfo)
{
SendText stText = new SendText(strHost,iPort,strInfo,new CommunClass.OnSend(OnSendDrawProgress)) ;
StartThread(new ThreadStart(stText.Send)) ;
}
下面是他调用用到的一些方法:
开始一个线程
private void StartThread(ThreadStart target)
{
Thread doStep = new Thread(target) ;
doStep.IsBackground = true ;
doStep.Start() ;
}
发送一部分(本文设置的是1024字节)成功后的回调方法
public void OnSendDrawProgress(int iTotal,int iSending)
{
if (iTotal != pbMain.Maximum)
pbMain.Maximum = iTotal ;
pbMain.Value = iSending ;
}
因为使用的是线程,所以发送文本使用的是一个发送文本类的方法,该类如下:
public class SendText
{
private string Host ;
private int Port ;
private string Info ;
private CommunClass.OnSend onsend ;
public SendText(string strHost,int iPort,string strInfo,
CommunClass.OnSend onSend)
{
Host = strHost ;
Port = iPort ;
Info = strInfo ;
onsend = onSend ;
}
public void Send()
{
Socket s = null ;
try
{
s = CommunClass.ConnectToServer(Host,Port) ;
CommunClass.WriteCommandToSocket(s,"SENDTEXT") ;
CommunClass.WriteCommandDescToSocket(s,"") ;
CommunClass.WriteDynamicTextToSocket(s,Info,onsend) ;
}
catch (Exception e)
{
MessageBox.Show(e.Message) ;
}
finally
{
if (s != null)
s.Close() ;
}
}
}//end class
这样就可以使用一个线程发送文本了。
发送文件的方法也类似:
private void StartSendFile(string strHost,int iPort,string strFile)
{
SendFile sfFile = new SendFile(strHost,iPort,strFile,this.pbMain) ;
pbMain.Value = 0 ;
StartThread(new ThreadStart(sfFile.Send)) ;
}
发送文件的类:
public class SendFile
{
private string Host ;
private int Port ;
private string FileToSend ;
private ProgressBar pbar;
public SendFile(string strHost,int iPort,string strFile,ProgressBar pbMain)
{
Host = strHost ;
Port = iPort ;
FileToSend = strFile ;
pbar = pbMain ;
}
public void Send()
{
Socket s = null ;
try
{
s = CommunClass.ConnectToServer(Host,Port) ;
CommunClass.WriteCommandToSocket(s,"SENDFILE") ;
CommunClass.WriteCommandDescToSocket(s,"") ;
CommunClass.WriteFileToSocket(s,FileToSend,new CommunClass.OnSend(OnSendDrawProgress)) ;
}
catch (Exception e)
{
MessageBox.Show(e.Message) ;
}
finally
{
if (s != null)
s.Close() ;
}
}
public void OnSendDrawProgress(int iTotal,int iSending)
{
if (iTotal != pbar.Maximum)
pbar.Maximum = iTotal ;
pbar.Value = iSending ;
}
}//end class
当然,你发送一个命令让服务器端启动一个程序(靠,这不成木马了吗?)也可以:
俺这里只给出一部分代码,其余的您自己可以发挥以下:
public class ExeCuteFile
{
private string Host ;
private int Port ;
private string FileName ;
private string cmdParam ;
public ExeCuteFile(string strHost,int iPort,string strFileName,string strCmdParam)
{
Host = strHost ;
Port = iPort ;
FileName = strFileName ;
cmdParam = strCmdParam ;
}
public void Send()
{
Socket s = null ;
try
{
s = CommunClass.ConnectToServer(Host,Port) ;
CommunClass.WriteCommandToSocket(s,"EXECUTEFILE") ;
CommunClass.WriteCommandDescToSocket(s,FileName) ;
CommunClass.WriteDynamicTextToSocket(s,"",null) ;
MessageBox.Show(CommunClass.ReadDynamicTextFromSocket(s)) ;
}
catch (Exception e)
{
MessageBox.Show(e.Message) ;
}
finally
{
if (s != null)
s.Close() ;
}
}
}
下面是服务器端接受信息的代码:
创建监听:
/// <summary>
/// 再给定的主机和端口上创建监听程序
/// </summary>
/// <param name="strAddress"></param>
/// <param name="iPort"></param>
private void BuildingServer(string strAddress,int iPort)
{
IPAddress ipAddress = Dns.Resolve(strAddress).AddressList[0];
try
{
listener = new TcpListener(ipAddress, iPort);
}
catch ( Exception e)
{
AddInfo(e.Message) ;
}
}
<b>开始监听:</b>
/// <summary>
/// 开始监听
/// </summary>
private void StartListen()
{
bool done = false;
listener.Start();
while (!done)
{
Socket s = listener.AcceptSocket() ;
if(s != null)
{
DealWithSocket dws = new DealWithSocket(s,this.tbLog) ;
StartThread(new ThreadStart(dws.DealWith)) ;
}
}
}
private void StartThread(ThreadStart target)
{
Thread doStep = new Thread(target) ;
doStep.IsBackground = true ;
doStep.Start() ;
}
开始监听后,对于每一个监听到的客户端的连接都用一个单独的线程来处理,处理通过类DealWithSocket来完成,下面是类代码:
public class DealWithSocket
{
private Socket s = null ;
private TextBox tbLog = null ;
public DealWithSocket(Socket newSocket,TextBox tbInfo)
{
s = newSocket ;
tbLog = tbInfo ;
}
public void DealWith()
{
string strCmd = CommunClass.ReadCommandFromSocket(s) ;
string strDesc = CommunClass.ReadCommandDescFromSocket(s) ;
AddInfo(strCmd) ;
switch(strCmd)
{
case "SENDFILE" :
CommunClass.ReadDynamicFileFromSocket(s,"e:\\rrr.txt") ;
break ;
case "EXECUTEFILE" :
string strParam = CommunClass.ReadDynamicTextFromSocket(s) ;
string strResult = ExeCuteFile(strDesc,strParam) ;
CommunClass.WriteDynamicTextToSocket(s,strResult,null) ;
break ;
default:
string strDetail = CommunClass.ReadDynamicTextFromSocket(s) ;
AddInfo(strDetail) ;
break ;
}
try
{
s.Close() ;
}
catch (Exception e)
{
AddInfo(e.Message) ;
}
}
private void AddInfo(string strInfo)
{
string Info = DateTime.Now.ToLongTimeString() + " "+ strInfo +"\r\n" ;
tbLog.Text += Info ;
tbLog.Refresh() ;
}
private string ExeCuteFile(string strFileName,string strCmdParam)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process() ;
proc.StartInfo.FileName = strFileName ;
proc.StartInfo.Arguments = strCmdParam ;
try
{
proc.Start() ;
return "OK" ;
}
catch(Exception err)
{
return err.Message ;
}
}
}//end class