C#Socket通讯(二)
/// 线程执行体,转发消息
/// </summary>
/// <param name="obj">传递给线程执行体的用户名,用以与用户通信 </param>
private void ThreadFunc(object obj)
{
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket;
//主循环
while (true)
{
try
{ //接受第一个数据包。
//由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断,
//这里的实现不够优雅,但不失为此简单模型的一个解决之道。
byte[] packetBuff = new byte[_maxPacket];
clientSkt.Receive(packetBuff);
string _str = Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');
//如果是发给不在线好友的信息
if (_str.StartsWith("cmd::FriendMessage"))
{
string UserName = _str.Substring("cmd::FriendMessage".Length, 20).Trim();
string MessageS = _str.Substring("cmd::FriendMessage".Length + 20, _str.Length - "cmd::FriendMessage".Length - 20);
SaveMessage(obj as string, UserName, MessageS);
continue;
}
//如果是离线请求
if (_str.StartsWith("cmd::RequestLogout"))
{
_transmit_tb.Remove(obj);
UpdateFriendList((string)obj, false, "");
// string svrlog = string.Format("[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
// Console.WriteLine(svrlog);
//向所有客户机发送系统消息
//foreach (DictionaryEntry de in _transmit_tb)
//{
// string _clientName = de.Key as string;
// Socket _clientSkt = de.Value as Socket;
// _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
//}
Thread.CurrentThread.Abort();
}
//如果是请求好友列表
if (_str.StartsWith("cmd::RequestFriendList"))
{
SerializeFriendList(obj, clientSkt);
// 将该用户不在线时的信息发送给用户
DataTable TabMessage = ReadMessage(obj as string);
if (TabMessage != null)
{
foreach (DataRow myrow in TabMessage.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"))
{
DataTable TabFind = TabUser.Clone();
DataRow [] FindRow =null ;
string UserName = _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 (DataRow myrow in FindRow)
{
TabFind.ImportRow(myrow);
}
clientSkt.Send(Encoding.Unicode.GetBytes("Find::FindFriend"));
IFormatter format = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
format.Serialize(stream, TabFind);
stream.Position = 0;
byte[] ret = new byte[_maxPacket];
int count = 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"))
{
string UserName = _str.Substring("Find::AddFriendAsk".Length, _str.Length - "Find::AddFriendAsk".Length);
//通过转发表查找接收方的套接字
if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(UserName))
{
Socket receiverSkt = _transmit_tb[UserName] as Socket;
receiverSkt.Send(Encoding.Unicode.GetBytes("Find::AddFriendAsk" + obj as string));
}
//这里不需要再继续接受后继数据包了,跳出当前循环体。
continue;
}
/// </summary>
/// <param name="obj">传递给线程执行体的用户名,用以与用户通信 </param>
private void ThreadFunc(object obj)
{
//通过转发表得到当前用户套接字
Socket clientSkt = _transmit_tb[obj] as Socket;
//主循环
while (true)
{
try
{ //接受第一个数据包。
//由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断,
//这里的实现不够优雅,但不失为此简单模型的一个解决之道。
byte[] packetBuff = new byte[_maxPacket];
clientSkt.Receive(packetBuff);
string _str = Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');
//如果是发给不在线好友的信息
if (_str.StartsWith("cmd::FriendMessage"))
{
string UserName = _str.Substring("cmd::FriendMessage".Length, 20).Trim();
string MessageS = _str.Substring("cmd::FriendMessage".Length + 20, _str.Length - "cmd::FriendMessage".Length - 20);
SaveMessage(obj as string, UserName, MessageS);
continue;
}
//如果是离线请求
if (_str.StartsWith("cmd::RequestLogout"))
{
_transmit_tb.Remove(obj);
UpdateFriendList((string)obj, false, "");
// string svrlog = string.Format("[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);
// Console.WriteLine(svrlog);
//向所有客户机发送系统消息
//foreach (DictionaryEntry de in _transmit_tb)
//{
// string _clientName = de.Key as string;
// Socket _clientSkt = de.Value as Socket;
// _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));
//}
Thread.CurrentThread.Abort();
}
//如果是请求好友列表
if (_str.StartsWith("cmd::RequestFriendList"))
{
SerializeFriendList(obj, clientSkt);
// 将该用户不在线时的信息发送给用户
DataTable TabMessage = ReadMessage(obj as string);
if (TabMessage != null)
{
foreach (DataRow myrow in TabMessage.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"))
{
DataTable TabFind = TabUser.Clone();
DataRow [] FindRow =null ;
string UserName = _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 (DataRow myrow in FindRow)
{
TabFind.ImportRow(myrow);
}
clientSkt.Send(Encoding.Unicode.GetBytes("Find::FindFriend"));
IFormatter format = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
format.Serialize(stream, TabFind);
stream.Position = 0;
byte[] ret = new byte[_maxPacket];
int count = 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"))
{
string UserName = _str.Substring("Find::AddFriendAsk".Length, _str.Length - "Find::AddFriendAsk".Length);
//通过转发表查找接收方的套接字
if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(UserName))
{
Socket receiverSkt = _transmit_tb[UserName] as Socket;
receiverSkt.Send(Encoding.Unicode.GetBytes("Find::AddFriendAsk" + obj as string));
}
//这里不需要再继续接受后继数据包了,跳出当前循环体。
continue;
}
浙公网安备 33010602011771号