俺的程序分三部分,包括發送部分、接受部分和一個兩者共享的通訊基類,這個基類才是俺心血的結晶:)
一、通訊基類
using system;
using system.net.sockets;
using system.net ;
using system.io ;
using system.windows.forms;
using system.text;
namespace baseclass
{
/// <summary>
/// 傳送信息的格式為 給定長度的命令部分+給定長度的命令注釋部分+可變長度的長度信息+可變長度的信息部分
/// </summary>
public class communclass
{
public communclass()
{
//
// todo: 在此處添加構造函數邏輯
//
}
/// <summary>
/// 命令部分的長度
/// </summary>
private static readonly int cmdlen = 50 ;
/// <summary>
/// 命令注釋部分的長度
/// </summary>
private static readonly int desclen = 100 ;
/// <summary>
/// 可變長度的長度信息部分所占的字節數
/// </summary>
private static readonly int dynamiclengthlen = 10 ;
/// <summary>
/// 每次處理可變信息部分的長度
/// </summary>
private static readonly int deallen = 1024 ;
/// <summary>
/// /應答的最大長度
/// </summary>
private static readonly int responlen = 20 ;
/// <summary>
/// 用于填充命令或注釋不足長度部分的字符
/// </summary>
private static readonly char fillchar = '^' ;
/// <summary>
/// 成功發送一部分數據后的回調方法(也可以認為是觸發的事件,但嚴格來說還不是)
/// </summary>
public delegate void onsend(int itotal,int isending) ;
/// <summary>
/// 根據給定的服務器和端口號建立連接
/// </summary>
/// <param name="strhost">服務器名</param>
/// <param name="iport">端口號</param>
/// <returns></returns>
public static socket connecttoserver(string strhost,int iport)
{
try
{
ipaddress ipaddress = dns.resolve(strhost).addresslist[0];
ipendpoint ippoint = new ipendpoint(ipaddress,iport) ;
socket s = new socket(addressfamily.internetwork,sockettype.stream,protocoltype.tcp) ;
s.connect(ippoint) ;
return s ;
}
catch (exception e)
{
throw (new exception("建立到服務器的連接出錯" + e.message)) ;
}
}
/// <summary>
/// 將文本寫到socket中
/// </summary>
/// <param name="s">要發送信息的socket</param>
/// <param name="strinfo">要發送的信息</param>
/// <returns>是否成功</returns>
public static bool writetexttosocket(socket s,string strinfo)
{
byte [] buf = encoding.utf8.getbytes(strinfo) ;
try
{
s.send(buf,0,buf.length,socketflags.none) ;
return true ;
}
catch(exception err)
{
messagebox.show("發送文本失敗!"+err.message) ;
return false ;
}
}
/// <summary>
/// 將命令文本寫到socket中
/// </summary>
/// <param name="s">要發送命令文本的socket</param>
/// <param name="strinfo">要發送的命令文本</param>
/// <returns>是否成功</returns>
public static bool writecommandtosocket(socket s,string strcmd)
{
if (strcmd == "")
strcmd = "nop" ;
strcmd = strcmd.padright(cmdlen,fillchar) ;
return writetexttosocket(s,strcmd) ;
}
/// <summary>
/// 將命令注釋寫到socket中
/// </summary>
/// <param name="s">要發送命令注釋的socket</param>
/// <param name="strinfo">要發送的命令注釋</param>
/// <returns>是否成功</returns>
public static bool writecommanddesctosocket(socket s,string strdesc)
{
if (strdesc == "")
strdesc = "0" ;
strdesc = strdesc.padright(desclen,fillchar) ;
return writetexttosocket(s,strdesc) ;
}
/// <summary>
/// 發送可變信息的字節數
/// </summary>
/// <param name="s">要發送字節數的socket</param>
/// <param name="ilen">字節數</param>
/// <returns>是否成功</returns>
public static bool writedynamiclentosocket(socket s,int ilen)
{
string strlen = ilen.tostring().padright(dynamiclengthlen,fillchar) ;
return writetexttosocket(s,strlen) ;
}
/// <summary>
/// 將緩存的指定部分發送到socket
/// </summary>
/// <param name="s">要發送緩存的socket</param>
/// <param name="buf">要發送的緩存</param>
/// <param name="istart">要發送緩存的起始位置</param>
/// <param name="icount">要發送緩存的字節數</param>
/// <param name="iblock">每次發送的字節說</param>
/// <param name="sendsuccess">每次發送成功后的回調函數</param>
/// <returns>是否發送成功</returns>
public static bool writebuftosocket(socket s,byte [] buf,int istart,int icount,int iblock,onsend sendsuccess)
{
int isended = 0 ;
int isending = 0 ;
while(isended<icount)
{
if (isended + iblock <= icount)
isending = iblock ;
else
isending = icount - isended ;
s.send(buf,istart+isended,isending,socketflags.none) ;
isended += isending ;
if (readresponsionfromsocket(s)=="ok")
if (sendsuccess != null)
sendsuccess(icount,isended) ;
else
return false;
}
return true ;
}
/// <summary>
/// 將長度不固定文本發送到socket
/// </summary>
/// <param name="s">要發送文本的socket</param>
/// <param name="strtext">要發送的文本</param>
/// <param name="onsendtext">成功發送一部分文本后的回調函數</param>
/// <param name="settextlen">得到文本長度的回調函數</param>
/// <returns></returns>
public static bool writedynamictexttosocket(socket s,string strtext,
onsend onsendtext)
{
byte [] buf = encoding.utf8.getbytes(strtext) ;
int ilen = buf.length ;
try
{
writedynamiclentosocket(s,ilen) ;
return writebuftosocket(s,buf,0,ilen,deallen,onsendtext) ;
}
catch(exception err)
{
messagebox.show("發送文本失敗!"+err.message) ;
return false ;
}
}
/// <summary>
/// 將文件寫到socket
/// </summary>
/// <param name="s">要發送文件的socket</param>
/// <param name="strfile">要發送的文件</param>
/// <returns>是否成功</returns>
public static bool writefiletosocket(socket s,string strfile,
onsend onsendfile)
{
filestream fs = new filestream(strfile,filemode.open,fileaccess.read,fileshare.read) ;
int ilen = (int)fs.length ;
writedynamiclentosocket(s,ilen) ;
byte [] buf = new byte[ilen] ;
try
{
fs.read(buf,0,ilen) ;
return writebuftosocket(s,buf,0,ilen,deallen,onsendfile) ;
}
catch(exception err)
{
messagebox.show("發送文件失敗!"+err.message) ;
return false ;
}
finally
{
fs.close() ;
}
}
/// <summary>
/// 對方對自己消息的簡單回應
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string readresponsionfromsocket( socket s)
{
byte [] bufcmd = new byte[responlen] ;
int icount = s.receive(bufcmd) ;
string strrespon = encoding.utf8.getstring(bufcmd,0,icount) ;
return strrespon ;
}
/// <summary>
/// 從socket讀取命令
/// </summary>
/// <param name="s">要讀取命令的socket</param>
/// <returns>讀取的命令</returns>
public static string readcommandfromsocket( socket s)
{
byte [] bufcmd = new byte[cmdlen] ;
int icount = s.receive(bufcmd,0,cmdlen,socketflags.partial) ;
string strcommand = encoding.utf8.getstring(bufcmd,0,cmdlen) ;
return strcommand = strcommand.trimend(fillchar) ;
}
/// <summary>
/// 讀取命令注釋
/// </summary>
/// <param name="s">要讀取命令注釋的socket</param>
/// <returns>讀取的命令注釋</returns>
public static string readcommanddescfromsocket( socket s)
{
byte [] bufcmd = new byte[desclen] ;
int icount = s.receive(bufcmd,0,desclen,socketflags.partial) ;
string strcommand = encoding.utf8.getstring(bufcmd,0,desclen) ;
return strcommand = strcommand.trimend(fillchar) ;
}
/// <summary>
/// 讀取可變部分的長度
/// </summary>
/// <param name="s">要讀取可變部分長度的socket</param>
/// <returns>讀取的可變部分的長度</returns>
public static int readdynamiclenfromsocket( socket s)
{
byte [] bufcmd = new byte[dynamiclengthlen] ;
int icount = s.receive(bufcmd,0,dynamiclengthlen,socketflags.partial) ;
string strcommand = encoding.utf8.getstring(bufcmd,0,dynamiclengthlen) ;
return int.parse(strcommand.trimend(fillchar)) ;
}
/// <summary>
/// 讀取文本形式的可變信息
/// </summary>
/// <param name="s">要讀取可變信息的socket</param>
/// <returns>讀取的可變信息</returns>
public static string readdynamictextfromsocket( socket s)
{
int ilen = readdynamiclenfromsocket(s) ;
byte [] buf = new byte[ilen] ;
string strinfo = "" ;
int ireceiveded = 0 ;
int ireceiveing = 0 ;
while(ireceiveded<ilen)
{
if (ireceiveded + deallen <= ilen)
ireceiveing = deallen ;
else
ireceiveing = ilen - ireceiveded ;
s.receive(buf,ireceiveded,ireceiveing,socketflags.none) ;
communclass.writetexttosocket(s,"ok") ;
ireceiveded+= ireceiveing ;
}
strinfo = encoding.utf8.getstring(buf,0,ilen) ;
return strinfo ;
}
/// <summary>
/// 讀取文件形式的可變信息
/// </summary>
/// <param name="s">要讀取可變信息的socket</param>
/// <param name="strfile">讀出后的文件保存位置</param>
/// <returns>是否讀取成功</returns>
public static bool readdynamicfilefromsocket( socket s,string strfile)
{
int ilen = readdynamiclenfromsocket(s) ;
byte [] buf = new byte[ilen] ;
filestream fs = new filestream(strfile,filemode.create,fileaccess.write) ;
try
{
int ireceiveded = 0 ;
int ireceiveing = 0 ;
while(ireceiveded<ilen)
{
if (ireceiveded + deallen <= ilen)
ireceiveing = deallen ;
else
ireceiveing = ilen - ireceiveded ;  , ;
s.receive(buf,ireceiveded,ireceiveing,socketflags.none) ;
communclass.writetexttosocket(s,"ok") ;
ireceiveded+= ireceiveing ;
}
fs.write(buf,0,ilen) ;
return true ;
}
catch(exception err)
{
messagebox.show("接收文件失敗"+err.message) ;
return false ;
}
finally
{
fs.close() ;
}
}
}//end class
}//end namespace
上面是俺的通訊基礎類,有了這個類,再進行發送接受還不是小菜一碟嗎?
posted on 2004年08月06日 3:00 pm