【发布时间】:2016-01-17 09:20:45
【问题描述】:
在我的服务器端,我设置了一个单线程代码,每次客户端连接时都会创建一个新的 Socket 对象。然后,我将从客户端获得的任何内容与连接到数据包处理程序的套接字一起传递,并在那里进行计算。在我的主窗体中,我有一个通过实体框架填充的列表视图,每当来自已注册计算机的数据包连接时,我都会更新列表视图。所以我的问题是,当我更新它时,我可以从数据包处理程序类中将套接字对象传递给我的列表视图的标记属性吗?
我的服务器端代码:
private void ReceivedCallback(IAsyncResult result)
{
Socket clientSocket = result.AsyncState as Socket;
SocketError ER;
try
{
int bufferSize = clientSocket.EndReceive(result, out ER);
if (ER == SocketError.Success)
{
byte[] packet = new byte[bufferSize];
Array.Copy(_buffer, packet, packet.Length);
Console.WriteLine("Handling packet from IP:" + clientSocket.RemoteEndPoint.ToString());
//Handle packet stuff here.
PacketHandler.Handle(packet, clientSocket);
_buffer = new byte[61144];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
//clientSocket.BeginReceive(new byte[] { 0 }, 0, 0, 0, ReceivedCallback, clientSocket);
}
else
{
Console.WriteLine("No bytes received, we're closing the connection.");
clientSocket.Close();
}
}catch(SocketException ex)
{
Console.WriteLine("We caught a socket exception:" + ex.Message);
clientSocket.Close();
}
}
还有我的数据包处理程序类:
public static void Handle(byte[] packet, Socket clientSocket)
{
if (clientSocket.Connected)
{
if (packet.Length > 0)
{
IPEndPoint RemoteIP = (IPEndPoint)clientSocket.RemoteEndPoint;
ushort packetLength = BitConverter.ToUInt16(packet, 0);
ushort packetType = BitConverter.ToUInt16(packet, 2);
ushort packetID = BitConverter.ToUInt16(packet, 4);
Console.WriteLine("We received a packet of Type: {0}, ID: {1} FROM {2}", packetType, packetID, RemoteIP.ToString());
if (packetType == 1)
{
switch (packetID)
{
case 1://Check if computer is registered in the database
CheckRegisteredRequest request1 = new CheckRegisteredRequest(packet);
Console.WriteLine("We received (Case 1): " + request1.Text);
string Response = "";
bool found = false;
ServerDbContext database = new ServerDbContext();
foreach (computers pcs in database.computers)
{
if (pcs.name == request1.Text.Split(',')[0])
{
found = true;
if (pcs.computer_ip == request1.Text.Split(',')[1])
{
//We found a computer with that name and ip address
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
computers registeredPC;
var name = request1.Text.Split(',')[0];
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
else
{
//We found a computer with that name but a different ip address, update it
var name = request1.Text.Split(',')[0];
var registeredPC = new computers();
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
var ip = request1.Text.Split(',')[1];
registeredPC.computer_ip = ip;
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
}
}
if (!found)
{
//There is no computer with that name in the database so send false
Response = "false";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
}
break;... and so on....
所以我已经通过处理程序进行了尝试:
这是我的自定义事件处理程序 Args:
public class TextArgs : EventArgs
{
#region Fields
private string szMessage;
private Socket _sockets123;
#endregion Fields
#region ConstructorsH
public TextArgs(string TextMessage,Socket sock)
{
if (sock != null)
{
_sockets123 = sock;
szMessage = TextMessage;
}
else
{
szMessage = TextMessage;
}
}
#endregion Constructors
#region Properties
public string Message
{
get { return szMessage; }
set { szMessage = value; }
}
public Socket _socket
{
get { return _sockets123; }
set { _sockets123 = value; }
}
#endregion Properties
}
这就是我在 PacketHandler 类中定义该处理程序的方式: 公共静态事件 LogsEventHandler 反馈;
private static void RaiseFeedback(string p, Socket sock)
{
LogsEventHandler handler = Feedback;
if (handler != null)
{
handler(null,new TextArgs(p,sock));
}
}
每当计算机注册或连接时,我都会执行以下操作:
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], clientSocket);
或
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], null);
这两种方法的事件在我的主要形式中触发:
private void OnFeedbackReceived(object sender, TextArgs e)
{
Invoke((MethodInvoker)delegate
{
UpdateComputers();
UpdateGUI(e.Message,e._socket);
}
);
}
public void UpdateGUI(string s, Socket sock)
{
LogBox.Text += s;
LogBox.AppendText(Environment.NewLine);
using (var context = new ServerDbContext())
{
var PCInfo = context.viewUsersInfo;
dataGridView1.DataSource = PCInfo.ToList();
}
if (sock != null)
{
ListViewItem item = ComputersList.FindItemWithText(s.Split(':')[1].ToString());
item.Tag = sock;
}
}
【问题讨论】:
-
标签是对象。当你尝试时发生了什么?
-
我试过这样: ListViewItem item = ComputersList.FindItemWithText(s.Split(':')[1].ToString()); item.Tag = 袜子;但由于某种原因,它无法获取该对象,我正在通过 EventHandler 将对象正确传递给它。
-
获取该对象不起作用你能解释一下吗?还显示您使用的代码?你把它扔回
socket,对吧?另外:请不要在 cmets 中添加代码;而是编辑问题,它看起来不错并且很容易找到和阅读..Socket theSocket = null; if (lvi.Tag != null) theSocket = lvi.Tag as Socket; if (theSocket != null) ... -
好的,我已经更改了问题,并添加了正在发生的事情。
-
我看到你是如何设置标签的,但我看不到你把它拉出来的地方。另外:这是 private Socket _socekt; 错字吗?还有:是 set { _socket = value; } //我在这里得到一个系统堆栈溢出异常 真正的问题是什么?显然你不能直接设置属性;通常它会被称为
Socket或TheSocket。 setter 是一个无限循环。尽可能用自动的 setter 和 getter 替换:public Socket MySocket { get; set;};
标签: c# sockets listview tags listviewitem