我的C#Windows窗体的一部分是对等(仅两个用户)聊天。 我使用.Net套接字。
我想做的是,只要有两个用户都可以聊天,他们就可以聊天。但是,当其中一个关闭程序然后再次打开它时,会出现许多问题。或者只有一个人在线时,我会收到此异常。
“远程主机强行关闭了现有连接。”
我尝试使用Socket.Close和Socket.ShutDown。我还尝试通过再次定义它来重新初始化套接字变量。一切似乎都行不通。我愿意接受任何建议,甚至可以使用不同的库或方法。
代码如下:
namespace TextChatApp
{
public partial class Form1 : Form
{
//attributes:
Socket sck;
EndPoint epLocal, epRemote;
public Form1()
{
InitializeComponent();
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
textBox1.Text=GetLocalIP();
textBox3.Text = GetLocalIP();
textBox2.Text = "8001";
textBox4.Text = "8000";
send.Enabled = false;
connectEndPoint();
InitTimer();
}
private void MessageCallBack(IAsyncResult aResult)
{
try
{
int size = sck.EndReceiveFrom(aResult, ref epRemote);
if(size>0)
{
byte[] receivedData = new byte[1500];
receivedData = (byte[])aResult.AsyncState;
ASCIIEncoding eEncoding = new ASCIIEncoding();
string receivedMessage = eEncoding.GetString(receivedData);
listBox1.Items.Add("From a friend: "+receivedMessage);
}
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
}
catch(Exception exp)
{
MessageBox.Show("Exception Small Chat: " + exp.ToString());
}
}
private void start_Click(object sender, EventArgs e)
{
}
public void connectEndPoint()
{
try
{
epLocal = new IPEndPoint(IPAddress.Parse(textBox1.Text), Convert.ToInt32(textBox2.Text));
sck.Bind(epLocal);
epRemote = new IPEndPoint(IPAddress.Parse(textBox3.Text), Convert.ToInt32(textBox4.Text));
sck.Connect(epRemote);
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
start.Enabled = false;
start.Text = "Connected";
send.Enabled = true;
textBox5.Focus();
}
catch (Exception exp)
{
}
}
private void send_Click(object sender, EventArgs e)
{
try
{
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
byte[] msg = new byte[1500];
msg = encoding.GetBytes(textBox5.Text);//
sck.Send(msg);
listBox1.Items.Add("You: " + textBox5.Text);
textBox5.Clear();
}
catch(Exception exp)
{
MessageBox.Show("Exception Small Chat: " + exp.ToString());
}
}
答案 0 :(得分:0)
我想我解决了自己的问题。 由于在发送数据时触发了异常,并且端点已关闭或未连接,因此我应该在发送数据之前检查它是否已连接。
但是,没有直接的方法可以找到端点是否已连接。 由于当我发送数据且端点处于关闭状态时会触发异常,因此该异常成为我指示端点处于关闭状态且连接断开的指示器。因此,我要做的是在“ Catch”语句中再次创建Socket,然后每隔一段时间重试一次,直到再次连接Socket。
每次触发异常时,我再次创建Socket的原因是因为Socket不稳定,并且会导致许多连接问题。因此,最好重新创建它,而不要不稳定。
这是我包含的代码
private void MessageCallBack(IAsyncResult aResult)
{
try
{
int size = sck.EndReceiveFrom(aResult, ref epRemote);
if(size>0)
{
byte[] receivedData = new byte[1500];
receivedData = (byte[])aResult.AsyncState;
ASCIIEncoding eEncoding = new ASCIIEncoding();
string receivedMessage = eEncoding.GetString(receivedData);
listBox1.Invoke(new MethodInvoker(delegate {
listBox1.Items.Add("From a friend: " + receivedMessage); }));
}
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None,
ref epRemote, new AsyncCallback(MessageCallBack), buffer);
}
catch(Exception exp)
{ /* here is the solution, when the Catch is triggered, close the
socket and recreate it to avoid the issues that I been having of
not sending messages and instability. I also added some functions
that would keep sending the status and //being checked on the other
side in order to keep online/offline status.*/
sck.Close();
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, true);
connectEndPoint();
//MessageBox.Show("Exception Small Chat: " + exp.ToString());
}
}