Socket通讯c#.docx
《Socket通讯c#.docx》由会员分享,可在线阅读,更多相关《Socket通讯c#.docx(86页珍藏版)》请在冰豆网上搜索。
Socket通讯c#
publicclassXmlSocket
{
//异步socket诊听
//Incomingdatafromclient.从客户端传来的数据
publicstaticstringdata=null;
//Threadsignal.线程用一个指示是否将初始状态设置为终止的布尔值初始化ManualResetEvent类的新实例。
publicstaticManualResetEventallDone=newManualResetEvent(false);
//staticvoidMain(string[]args)
//{
//StartListening();
//}
publicstaticvoidStartListening()
{
//Databufferforincomingdata.传入数据缓冲
byte[]bytes=newByte[1024];
//Establishthelocalendpointforthesocket.建立本地端口
//TheDNSnameofthecomputer
//runningthelisteneris"".
IPAddressipAddress;
StringipString=ConfigurationManager.AppSettings.Get("SocketIP");
if(ipString==null||ipString==String.Empty)
{
IPHostEntryipHostInfo=Dns.GetHostEntry(Dns.GetHostName());
ipAddress=ipHostInfo.AddressList[0];
}
else
{
ipAddress=IPAddress.Parse(ipString);
}
intport;
StringportString=ConfigurationManager.AppSettings.Get("SocketPort");
if(portString==null||portString==String.Empty)
{
port=11001;
}
else
{
port=int.Parse(portString);
}
IPEndPointlocalEndPoint=newIPEndPoint(ipAddress,port);
//CreateaTCP/IPsocket.
Socketlistener=newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
//Bindthesockettothelocalendpointandlistenforincomingconnections.绑定端口和数据
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while(true)
{
//Settheeventtononsignaledstate.设置无信号状态的事件
allDone.Reset();
//Startanasynchronoussockettolistenforconnections.重新启动异步连接
listener.BeginAccept(newAsyncCallback(AcceptCallback),listener);
//Waituntilaconnectionismadebeforecontinuing.等待连接创建后继续
allDone.WaitOne();
}
}
catch(Exceptione)
{
//
}
}
publicstaticvoidAcceptCallback(IAsyncResultar)
{
try
{
//Signalthemainthreadtocontinue.接受回调方法该方法的此节向主应用程序线程发出信号,
//让它继续处理并建立与客户端的连接
allDone.Set();
//Getthesocketthathandlestheclientrequest.获取客户端请求句柄
Socketlistener=(Socket)ar.AsyncState;
Sockethandler=listener.EndAccept(ar);
//Createthestateobject.
StateObjectstate=newStateObject();
state.workSocket=handler;
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
newAsyncCallback(ReadCallback),state);
}
catch(Exceptione)
{
//
}
}
///
///与接受回调方法一样,读取回调方法也是一个AsyncCallback委托。
///该方法将来自客户端套接字的一个或多个字节读入数据缓冲区,然后再次调用BeginReceive方法,直到客户端发送的数据完成为止。
///从客户端读取整个消息后,在控制台上显示字符串,并关闭处理与客户端的连接的服务器套接字。
///
///IAsyncResult委托
publicstaticvoidReadCallback(IAsyncResultar)
{
try
{
Stringcontent=String.Empty;
//Retrievethestateobjectandthehandlersocket创建自定义的状态对象fromtheasynchronousstateobject.
StateObjectstate=(StateObject)ar.AsyncState;
Sockethandler=state.workSocket;//处理的句柄
//Readdatafromtheclientsocket.读出
intbytesRead=handler.EndReceive(ar);
if(bytesRead>0)
{
//业务代码
stringresult=DoSomeThing(...);
Stringlen=Encoding.UTF8.GetBytes(result).Length.ToString().PadLeft(8,'0');
log.writeLine(len);
Send(len+result,handler);
}
}
catch(Exceptione)
{
//
}
}
privatestaticvoidSend(Stringdata,Sockethandler)
{
try
{
//ConvertthestringdatatobytedatausingUTF8encoding.
byte[]byteData=Encoding.UTF8.GetBytes(data);
//Beginsendingthedatatotheremotedevice.
handler.BeginSend(byteData,0,byteData.Length,0,
newAsyncCallback(SendCallback),handler);
}
catch(Exceptione)
{
//
}
}
///
///发送
///
///
privatestaticvoidSendCallback(IAsyncResultar)
{
try
{
//Retrievethesocketfromthestateobject.
Sockethandler=(Socket)ar.AsyncState;
//Completesendingthedatatotheremotedevice.向远端发送数据
intbytesSent=handler.EndSend(ar);
StateObjectstate=newStateObject();
state.workSocket=handler;
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,newAsyncCallback(ReadCallback),state);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch(Exceptione)
{
//
}
}
publicstaticvoidStopListening()
{
allDone.Close();
log.close();
}
///
///具体处理业务的方法
///
///
privatestaticstringDoSomething(inti)
{
//具体业务代码,返回需要返回的字符串信息
}
///
///写日志方法
///
///写入内容
publicstaticvoidWriteLog(stringstrLog)
{
//写入日志代码
}
}
∙对我有用[9]
∙丢个板砖[0]
∙引用
∙举报
∙管理
∙TOP
回复次数:
800
∙
∙sjm2003
∙(地上的菜鸟)
∙
∙等 级:
∙
#1楼得分:
0回复于:
2008-06-2308:
27:
19
C#code
///线程执行体,转发消息
///
///传递给线程执行体的用户名,用以与用户通信
privatevoidThreadFunc(objectobj)
{
//通过转发表得到当前用户套接字
SocketclientSkt=_transmit_tb[obj]asSocket;
//主循环
while(true)
{
try
{//接受第一个数据包。
//由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断,
//这里的实现不够优雅,但不失为此简单模型的一个解决之道。
byte[]packetBuff=newbyte[_maxPacket];
clientSkt.Receive(packetBuff);
string_str=Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');
//如果是发给不在线好友的信息
if(_str.StartsWith("cmd:
:
FriendMessage"))
{
stringUserName=_str.Substring("cmd:
:
FriendMessage".Length,20).Trim();
stringMessageS=_str.Substring("cmd:
:
FriendMessage".Length+20,_str.Length-"cmd:
:
FriendMessage".Length-20);
SaveMessage(objasstring,UserName,MessageS);
continue;
}
//如果是离线请求
if(_str.StartsWith("cmd:
:
RequestLogout"))
{
_transmit_tb.Remove(obj);
UpdateFriendList((string)obj,false,"");
//stringsvrlog=string.Format("[系统消息]用户{0}在{1}已断开...当前在线人数:
{2}\r\n\r\n",obj,DateTime.Now,_transmit_tb.Count);
//Console.WriteLine(svrlog);
//向所有客户机发送系统消息
//foreach(DictionaryEntrydein_transmit_tb)
//{
//string_clientName=de.Keyasstring;
//Socket_clientSkt=de.ValueasSocket;
//_clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
//}
Thread.CurrentThread.Abort();
}
//如果是请求好友列表
if(_str.StartsWith("cmd:
:
RequestFriendList"))
{
SerializeFriendList(obj,clientSkt);
//将该用户不在线时的信息发送给用户
DataTableTabMessage=ReadMessage(objasstring);
if(TabMessage!
=null)
{
foreach(DataRowmyrowinTabMessage.Rows)
{
if(myrow["SendUserName"].ToString()=="System:
:
Message")
{
clientSkt.Send(Encoding.Unicode.GetBytes(myrow["Message"].ToString()));
}
else
{
clientSkt.Send(Encoding.Unicode.GetBytes("cmd:
:
FriendMessage"+myrow["SendUserName"].ToString().PadRight(20,'')+myrow["Message"].ToString()));
}
}
}//这里不需要再继续接受后继数据包了,跳出当前循环体。
continue;
}
////如果是请求好友列表
//if(_str.StartsWith("cmd:
:
RequestOnLineList"))
//{
//byte[]onlineBuff=SerializeOnlineList();
////先发送响应信号,用户客户机的判断
//clientSkt.Send(Encoding.Unicode.GetBytes("cmd:
:
RequestOnLineList"));
//clientSkt.Send(onlineBuff);
////这里不需要再继续接受后继数据包了,跳出当前循环体。
//continue;
//}//查找用户
if(_str.StartsWith("Find:
:
FindFriend"))
{
DataTableTabFind=TabUser.Clone();
DataRow[]FindRow=null;
stringUserName=_str.Substring("Find:
:
FindFriend".Length,_str.Length-"Find:
:
FindFriend".Length);
if(UserName.Equals("Find:
:
WhoOnLine"))
{//看谁在线
FindRow=TabUser.Select("ZX=1");
}
else//精确查找
{
FindRow=TabUser.Select("UserName='"+UserName+"'");
}
foreach(DataRowmyrowinFindRow)
{
TabFind.ImportRow(myrow);
}
clientSkt.Send(Encoding.Unicode.GetBytes("Find:
:
FindFriend"));
IFormatterformat=newBinaryFormatter();
MemoryStreamstream=newMemoryStream();
format.Serialize(stream,TabFind);
stream.Position=0;
byte[]ret=newbyte[_maxPacket];
intcount=0;
count=stream.Read(ret,0,_maxPacket);
while(count>0)
{
clientSkt.Send(ret);
count=stream.Read(ret,0,_maxPacket);
}
clientSkt.Send(Encoding.Unicode.GetBytes("Find:
:
FindFriendEnd"));
stream.Close();
TabFind=null;
FindRow=null;//这里不需要再继续接受后继数据包了,跳出当前循环体。
continue;
}//请求添加好友
if(_str.StartsWith("Find:
:
AddFriendAsk"))
{
stringUserName=_str.Substring("Find:
:
AddFriendAsk".Length,_str.Length-"Find:
:
AddFriendAsk".Length);
//通过转发表查找接收方的套接字
if(_transmit_tb.Count!
=0&&_transmit_tb.ContainsKey(UserName))
{
SocketreceiverSkt=_transmit_tb[UserName]asSocket;
receiverSkt.Send(Encoding.Unicode.GetBytes("Find:
:
AddFriendAsk"+objasstring));
}
//这里不需要再继续接受后继数据包了,跳出当前循环体。
continue;
}
//回复答应添加好友
if(_str.StartsWith("Find:
:
AddFriendYes"))
{
stringUserName=_str.Substring("Find:
:
AddFriendYes".Length,_str.Length-"Find:
:
AddFriendYes".Length);
////保存数据
DataTableTabmyFriend=newDataTable();
//保存该用户
TabmyFriend.ReadXml(MyPath+"\\UserFriend\\"+objasstring+".xml");
DataRownewRow=TabmyFriend.NewRow();
newRow["UserName"]=UserName;
TabmyFriend.Rows.Add(newRow);
TabmyFriend.WriteXml(MyPath+"\\UserFriend\\"+objasstring+".xml",XmlWriteMode.WriteSchema,false);
//保存其好友
TabmyFriend=newDataTable();
TabmyFriend.ReadXml(MyPath+"\\UserFriend\\"+UserName+".xml");
DataRownewRow1=TabmyFriend.NewRow();
newRow1["UserName"]=objasstring;
TabmyFriend.Rows.Add(newRow1);
TabmyFriend.WriteXml(MyPath+"\\UserFriend\\"+UserName+".xml",XmlWriteMode.WriteSchema,false);
TabmyFriend=null;
SerializeFriendList(obj,clientSkt);
∙对我有用[1]
∙丢个板砖[1]
∙引用
∙举报
∙管理
∙TOP
精华推荐:
程序员多少岁是合适结婚的
∙
∙sjm2003
∙(地上的菜鸟)
∙
∙等 级:
∙
#2楼得分:
0回复于:
2008-06-2308:
32:
35
C#code
//"开始"按钮事件
privatevoidbutton1_Click(objectsender,System.EventArgse){
//取得预保存的文件名
stringfileName=textBox3.Text.Trim();
//远程主机
stringhostName=textBox1.Text.Trim();
//端