socket接收不同步,大侠请进啊!

panliuwen 2009-09-30 09:44:46
当我从服务器端发送消息的时候,客户端可以接收到信息。服务器发完信息之后(假设最后一条发送的信息是fast),接着由客户端发送消息(假设客户端发送消息为weak),服务器接收到的信息是fast而不是客户端发送的weak。这是为什么呢?下面是我写的代码,就剩最后一个小问题了,真的烦死我了。哪位大侠帮我看看啊!

服务器端代码:

namespace UdpTcpServer
{
public partial class UdpTcpServerForm : Form
{
struct ClientInfo
{
public EndPoint endpoint;
public string strName;
}
ArrayList clientList;
Socket serverSocket;
byte[] byteData = new byte[1024];

public UdpTcpServerForm()
{
CheckForIllegalCrossThreadCalls = false;
clientList = new ArrayList();
InitializeComponent();
}

private void UdpTcpServerForm_Load(object sender, EventArgs e)
{
try
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.114"), 8080);
serverSocket.Bind(ipEndPoint);

IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
EndPoint epSender = (EndPoint)ipeSender;

byteData = new byte[1024];
serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);

if (lbUsers.Items.Count <= 0)
{
btnSendMessage.Enabled = false;
btnBrocast.Enabled = false;
btnSendFile.Enabled = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UdpTcpServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}


public void OnSend(IAsyncResult ar)
{
try
{
serverSocket.EndSend(ar);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UdpTcpServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void OnReceive(IAsyncResult ar)
{
try
{
IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
EndPoint epSender = (EndPoint)ipeSender;

//Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
serverSocket.EndReceiveFrom(ar, ref epSender);

string msgReceived = Encoding.Unicode.GetString(byteData);
string[] tokens = msgReceived.Split(new char[] { '|' });

if (tokens[0] == "login")
{
ClientInfo clientInfo = new ClientInfo();
clientInfo.endpoint = epSender;
clientInfo.strName = tokens[1];
clientList.Add(clientInfo);
lbUsers.Items.Add(tokens[1]);

btnBrocast.Enabled = true;
btnSendFile.Enabled = true;
btnSendMessage.Enabled = true;
}
else if (tokens[0] == "logout")
{
int nIndex = 0;

foreach (ClientInfo client in clientList)
{
string strEndPoint = client.endpoint.ToString();
string strepSender = epSender.ToString();

if (strEndPoint.Equals(strepSender))
{
clientList.RemoveAt(nIndex);
lbUsers.Items.RemoveAt(nIndex);
break;
}
++nIndex;
}

string strMessage = tokens[1];
rtbHistoryMessage.AppendText(strMessage);
}
else if (tokens[0] == "talk")
{
rtbHistoryMessage.AppendText(tokens[1]);

string message = "talk|"+tokens[1];
byteData = Encoding.Unicode.GetBytes(message);
serverSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epSender, new AsyncCallback(OnSend), epSender);
}

byteData=new byte[1024];
serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UdpTcpServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void btnSendMessage_Click(object sender, EventArgs e)
{
if (lbUsers.SelectedItems.Count > 0)
{
if (txtMessage.Text.Length > 0)
{
string sendMessage = "talk|" + "服务器:" + txtMessage.Text + "\n";
byteData = Encoding.Unicode.GetBytes(sendMessage);

foreach (string user in lbUsers.SelectedItems)
{
foreach (ClientInfo client in clientList)
{
if (client.strName.ToString().Trim()==user.Trim())
{
serverSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, client.endpoint, new AsyncCallback(OnSend), client.endpoint);
}
}
}
rtbHistoryMessage.AppendText("服务器:" + txtMessage.Text + Environment.NewLine);
txtMessage.Text = null;
}
else
{
MessageBox.Show("不能发送空信息!");
}
}
else
{
MessageBox.Show("请选择用户,再发送!");
}
}

private void btnBrocast_Click(object sender, EventArgs e)
{
string sendMessage = "talk|" + "服务器:" + txtMessage.Text + "\n" ;
byteData = Encoding.Unicode.GetBytes(sendMessage);

foreach (ClientInfo ci in clientList)
{
EndPoint epSender = ci.endpoint;
serverSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epSender, new AsyncCallback(OnSend), epSender);
}

rtbHistoryMessage.AppendText("服务器:" + txtMessage.Text + Environment.NewLine);
txtMessage.Text = null;
sendMessage = null;
}
}
}


...全文
359 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
x45224446 2010-09-19
  • 打赏
  • 举报
回复
看隐藏
ljb07976513524 2009-09-30
  • 打赏
  • 举报
回复
╮(╯▽╰)╭
likexx 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 panliuwen 的回复:]
我还是看不懂四楼的意思啊,真的烦恼啊
[/Quote]

你的数据全部来自byteData,对不对?

好,那么你在发的时候,给byteData赋了值,假设这是最后一个packet,发完之后,client端不会再发回来,所以OnReceive不会收到任何东西,对吧?

换句话说,OnReceive里面,因为最后一个packet已经发出去,而不会再收到任何东西,所以EndReceive()会持续一段时间,然后抛出exception。因为没有收到任何packet,所以byteData没有改变,仍然是你发出去时候的。

重复一遍,如果你还没看明白,在btnSendMessage_Click()里面把byteData换成local变量。为什么你要用一个member变量来处理?我没看到有任何好处,除了把你自己搅晕。
happyboyxq1985 2009-09-30
  • 打赏
  • 举报
回复
OnReceive里面这个地方根本就是显示你要发送的信息,这个里面没有接受信息的语句
string msgReceived = Encoding.Unicode.GetString(byteData);
接受信息应该是类似
int bytesRead = mSocket.EndReceive(ar);这样的
panliuwen 2009-09-30
  • 打赏
  • 举报
回复
我还是看不懂四楼的意思啊,真的烦恼啊
ncjcz 2009-09-30
  • 打赏
  • 举报
回复
IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
应该把接收到的自己的信息屏蔽吧
likexx 2009-09-30
  • 打赏
  • 举报
回复
你那个byteData,在Send里面:

string sendMessage = "talk|" + "服务器:" + txtMessage.Text + "\n";
byteData = Encoding.Unicode.GetBytes(sendMessage);

明白没有?

在server上:

server send 最后一个message: weak
byteData = "weak"

然后server这边的OnReceive()继续EndReceiveFrom----但是这个不会完成,因为client已经结束了,所以下面的byteData= new byte[1024]也就不会执行。

你这段代码的主要问题就是用byteData同时receive/send,还用的asyncronize 模式。拜托,反正你每次都要new,直接用local变量不久得了,何必自找麻烦?


[Quote=引用楼主 panliuwen 的回复:]
当我从服务器端发送消息的时候,客户端可以接收到信息。服务器发完信息之后(假设最后一条发送的信息是fast),接着由客户端发送消息(假设客户端发送消息为weak),服务器接收到的信息是fast而不是客户端发送的weak。这是为什么呢?下面是我写的代码,就剩最后一个小问题了,真的烦死我了。哪位大侠帮我看看啊!

服务器端代码:
C# codenamespace UdpTcpServer
{publicpartialclass UdpTcpServerForm : Form
{struct ClientInfo
{public EndPoint endpoint;publicstring strName;
}
ArrayList clientList;
Socket serverSocket;byte[] byteData=newbyte[1024];public UdpTcpServerForm()
{
CheckForIllegalCrossThreadCalls=false;
clientList=new ArrayList();
InitializeComponent();
}privatevoid UdpTcpServerForm_Load(object sender, EventArgs e)
{try
{
serverSocket=new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipEndPoint=new IPEndPoint(IPAddress.Parse("192.168.1.114"),8080);
serverSocket.Bind(ipEndPoint);

IPEndPoint ipeSender=new IPEndPoint(IPAddress.Any,0);
EndPoint epSender= (EndPoint)ipeSender;

byteData=newbyte[1024];
serverSocket.BeginReceiveFrom(byteData,0, byteData.Length, SocketFlags.None,ref epSender,new AsyncCallback(OnReceive), epSender);if (lbUsers.Items.Count<=0)
{
btnSendMessage.Enabled=false;
btnBrocast.Enabled=false;
btnSendFile.Enabled=false;
}
}catch (Exception ex)
{
MessageBox.Show(ex.Message,"UdpTcpServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}publicvoid OnSend(IAsyncResult ar)
{try
{
serverSocket.EndSend(ar);
}catch (Exception ex)
{
MessageBox.Show(ex.Message,"UdpTcpServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}privatevoid OnReceive(IAsyncResult ar)
{try
{
IPEndPoint ipeSender=new IPEndPoint(IPAddress.Any,0);
EndPoint epSender= (EndPoint)ipeSender;//Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); serverSocket.EndReceiveFrom(ar,ref epSender);string msgReceived= Encoding.Unicode.GetString(byteData);string[] tokens= msgReceived.Split(newchar[] {'|' });if (tokens[0]=="login")
{
ClientInfo clientInfo=new ClientInfo();
clientInfo.endpoint= epSender;
clientInfo.strName= tokens[1];
clientList.Add(clientInfo);
lbUsers.Items.Add(tokens[1]);

btnBrocast.Enabled=true;
btnSendFile.Enabled=true;
btnSendMessage.Enabled=true;
}elseif (tokens[0]=="logout")
{int nIndex=0;foreach (ClientInfo clientin clientList)
{string strEndPoint= client.endpoint.ToString();string strepSender= epSender.ToString();if (strEndPoint.Equals(strepSender))
{
clientList.RemoveAt(nIndex);
lbUsers.Items.RemoveAt(nIndex);break;
}++nIndex;
}string strMessage= tokens[1];
rtbHistoryMessage.AppendText(strMessage);
}elseif (tokens[0]=="talk")
{
rtbHistoryMessage.AppendText(tokens[1]);string message="talk|"+tokens[1];
byteData= Encoding.Unicode.GetBytes(message);
serverSocket.BeginSendTo(byteData,0, byteData.Length, SocketFlags.None, epSender,new AsyncCallback(OnSend), epSender);
}

byteData=newbyte[1024];
serverSocket.BeginReceiveFrom(byteData,0, byteData.Length, SocketFlags.None,ref epSender,new AsyncCallback(OnReceive), epSender);
}catch (Exception ex)
{
MessageBox.Show(ex.Message,"UdpTcpServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}privatevoid btnSendMessage_Click(object sender, EventArgs e)
{if (lbUsers.SelectedItems.Count>0)
{if (txtMessage.Text.Length>0)
{string sendMessage="talk|"+"服务器:"+ txtMessage.Text+"\n";
byteData= Encoding.Unicode.GetBytes(sendMessage);foreach (string userin lbUsers.SelectedItems)
{foreach (ClientInfo clientin clientList)
{if (client.strName.ToString().Trim()==user.Trim())
{
serverSocket.BeginSendTo(byteData,0, byteData.Length, SocketFlags.None, client.endpoint,new AsyncCallback(OnSend), client.endpoint);
}
}
}
rtbHistoryMessage.AppendText("服务器:"+ txtMessage.Text+ Environment.NewLine);
txtMessage.Text=null;
}else
{
MessageBox.Show("不能发送空信息!");
}
}else
{
MessageBox.Show("请选择用户,再发送!");
}
}privatevoid btnBrocast_Click(object sender, EventArgs e)
{string sendMessage="talk|"+"服务器:"+ txtMessage.Text+"\n" ;
byteData= Encoding.Unicode.GetBytes(sendMessage);foreach (ClientInfo ciin clientList)
{
EndPoint epSender= ci.endpoint;
serverSocket.BeginSendTo(byteData,0, byteData.Length, SocketFlags.None, epSender,new AsyncCallback(OnSend), epSender);
}

rtbHistoryMessage.AppendText("服务器:"+ txtMessage.Text+ Environment.NewLine);
txtMessage.Text=null;
sendMessage=null;
}
}
}


[/Quote]
panliuwen 2009-09-30
  • 打赏
  • 举报
回复
大侠,快啊,我急死了,不然就被炒了
zouyingbin 2009-09-30
  • 打赏
  • 举报
回复
http://bbs.yjxsoft.net/?u=627
panliuwen 2009-09-30
  • 打赏
  • 举报
回复
客户端代码

namespace UdpTcpClient
{
public partial class Form1 : Form
{
public Socket clientSocket;
public string strName;
public EndPoint epServer;
byte[] byteData = new byte[1024];
int portNo = 8080;

private string filename;
private string fullfilename;

public Form1()
{
CheckForIllegalCrossThreadCalls = false;

InitializeComponent();

btnSendFile.Enabled = false;
btnSendMessage.Enabled = false;
}

private void OnSend(IAsyncResult ar)
{
try
{
clientSocket.EndSend(ar);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UdpTcpClient: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void OnReceive(IAsyncResult ar)
{
try
{
clientSocket.EndReceive(ar);

string msgReceived =Encoding.Unicode.GetString(byteData);
string[] tokens = msgReceived.Split(new Char[] { '|' });

if (tokens[0] == "talk"&&tokens[1].Length>0)
{
rtbHistoryMessage.AppendText(tokens[1]);
}

byteData = new byte[1024];
clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epServer, new AsyncCallback(OnReceive), null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UdpTcpClient: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}


private void btnSign_Click(object sender, EventArgs e)
{
if (btnSign.Text == "登陆")
{
strName = txtNick.Text.Trim();

clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPAddress ip = IPAddress.Parse("192.168.1.114");
IPEndPoint ipep = new IPEndPoint(ip, portNo);
epServer = (EndPoint)ipep;

string sendMessage =string.Empty;
sendMessage = "login|" + strName + "\n";

byteData = Encoding.Unicode.GetBytes(sendMessage);
clientSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);

this.Text = "客户端用户:" + strName;

Initialize();

txtNick.Enabled = false;
btnSign.Enabled = false;
btnSendFile.Enabled = true;
}
}

private void Initialize()
{
byteData = new byte[1024];
clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epServer, new AsyncCallback(OnReceive), null);
}

private void btnSendMessage_Click(object sender, EventArgs e)
{
try
{
string sendMessage = "talk|" + txtNick.Text + ":" + txtMessage.Text + "\n";
byteData = Encoding.Unicode.GetBytes(sendMessage);

clientSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);

txtMessage.Text = null;
btnSendMessage.Enabled = false;
}
catch (Exception)
{
MessageBox.Show("无法向服务器发送消息!", "UdpTcpClient: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

}
}

[/code]
yagebu1983 2009-09-30
  • 打赏
  • 举报
回复
监视一下。。。
wartim 2009-09-30
  • 打赏
  • 举报
回复
好长啊,给你一个我项目里udp的例子
public String ReadTime(int DeviceStyle, String MACAddress, String IPAddress, int Port, int PCPort, String SysNo, int ReadTimeTime)
{
Functions Funcs = new Functions();

IPEndPoint RemoteIPEndPoint = new IPEndPoint(System.Net.IPAddress.Parse(IPAddress), Port);
using (UdpClient UC = new UdpClient(PCPort))
{
String SendInfo = "AA" + MACAddress + DeviceStyle.ToString() + SysNo + "02000000";
SendInfo += Funcs.CreateCheck(SendInfo);
UC.Connect(RemoteIPEndPoint);
Byte[] SendBytes = Encoding.ASCII.GetBytes(SendInfo);
UC.Send(SendBytes, SendBytes.Length);
IAsyncResult AR = UC.BeginReceive(null, null);
AR.AsyncWaitHandle.WaitOne(ReadTimeTime * 1000);
if (AR.IsCompleted)
{
Byte[] ReceiveBytes = UC.EndReceive(AR, ref RemoteIPEndPoint);
String ReceiveInfo = Encoding.ASCII.GetString(ReceiveBytes);
Consts.CommandInfo CI = new Consts.CommandInfo(ReceiveInfo);
Funcs.CheckCMDStatus(CI.CMDStatus);
if (CI.CMDType == Consts.ECMDType.ctDev)
if (CI.CMDCode == 0x02)
return "读取成功,消费机MAC地址[" + CI.DevMac + "]的返回的当前时间是 " + DateTime.FromOADate(Funcs.DevStrToDateTime(CI.CMDData)).ToString();
else
throw new Exception("操作失败。");
}
else
{
throw new Exception("操作超时。");
}
return String.Empty;
}
}
likexx 2009-09-30
  • 打赏
  • 举报
回复
重新看了一下你的程序,我刚才分析的不太对,我以为最后client没有返回data,但是好像你那个程序是由用户返回的。

总之解决方法还是把member变量改成local,然后trace一下byteData的变化,应该最后server端的OnReceive()并没receive到东西。

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧