c# Socket通信
(1) 我做了一个服务器工程和客户机工程,使用异步SOCKET,当同时运行两个工程的时候,进行通信每次点击客户端的“关闭连接”按钮时,服务器端就跳出程序,不再执行,不知道是为什么?
(2)当我将服务器端和客户端放置在一个对话框上时,不能相互发送数据,同时也当“关闭连接”时,程序退出!
--------------------编程问答-------------------- ...这样没人知道为什么
都看不到代码,你让人在这猜呀。。。 --------------------编程问答-------------------- “服务器端和客户端放置在一个对话框上时”这是什么意思啊?怎么放啊?不太明白你的意思。
你的“关闭连接”又是怎么写的?
你点击"关闭连接"时程序退出,有可能是出错了。程序就强制结束啊。
你调试一下啊。
还有听你这么描述,别人看不到代码,是无法帮你的。别人都不知道你是怎么写的。 --------------------编程问答--------------------
这是服务器端的代码:
namespace 城市燃气管网泄漏监测远程通讯系统
{
public partial class frmTextLink : Form
{
public frmTextLink()
{
InitializeComponent();
}
//以下是新加的
private IPAddress myIP = IPAddress.Parse("127.0.0.1");
private IPEndPoint MyServer;
private Socket sock;
private Socket handler;
private static ManualResetEvent Done = new ManualResetEvent(false);
//以上是新加的
private void button1_Click(object sender, EventArgs e) //开始监听按钮
{
try
{
myIP = IPAddress.Parse(textBox1.Text);
}
catch { MessageBox.Show("您输入的IP格式不正确,请重新输入"); }
try
{
MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(MyServer);
sock.Listen(50);
toolStripStatusLabel1.Text = " 主机 " + textBox1.Text + " 端口 " + textBox2.Text + " 开始监听....";
Thread thread = new Thread(new ThreadStart(targett));
thread.Start();
}
catch (Exception ee)
{
toolStripStatusLabel1.Text = ee.Message;
}
}
private void targett()
{
while (true)
{
//设为非终止
Done.Reset();
//异步开始接收
sock.BeginAccept(new AsyncCallback(AcceptCallback), sock);
//阻塞线程,知道收到信号
Done.WaitOne();
}
}
private void AcceptCallback(IAsyncResult ar)
{
//设为终止
Done.Set();
//获取状态
Socket listener = (Socket)ar.AsyncState;
//结束异步接收,并获取结果
handler = listener.EndAccept(ar);
//创建自定义类对象实例
StateObject state = new StateObject();
state.workSocket = handler;
toolStripStatusLabel1.Text = "与客户建立连接";
try
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");
//开始异步发送数据
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
//定义线程
Thread thread = new Thread(new ThreadStart(rec));
//开始接收数据线程
thread.Start();
}
private void SendCallback(IAsyncResult ar)
{
try
{
//获取状态
handler = (Socket)ar.AsyncState;
//结束发送
int bytesSent = handler.EndSend(ar);
}
catch { }
}
private void rec()
{
StateObject state = new StateObject();
state.workSocket = handler;
//开始异步接收数据
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
private void ReadCallback(IAsyncResult ar)
{
//获取状态
StateObject state = (StateObject)ar.AsyncState;
Socket tt = state.workSocket;
//结束异步读取数据,并获取结果
int bytesRead = handler.EndReceive(ar);
//贮存数据
state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
//转换为字符串
string content = state.sb.ToString();
//清楚state.sb内容
state.sb.Remove(0, content.Length);
//向richTextBox1写数据
richTextBox1.AppendText(content + "\r\n");
//重新开始接收
tt.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
private void button3_Click(object sender, EventArgs e) //停止监听按钮
{
try
{
sock.Close();
toolStripStatusLabel1.Text = " 主机 " + textBox1.Text + " 端口 " + textBox2.Text + " 停止监听!";
}
catch
{
MessageBox.Show("监听尚未开始,关闭无效!");
}
}
private void button2_Click(object sender, EventArgs e) //发送信息按钮
{
try
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(richTextBox2.Text+"\n\r");
//异步开始发送数据
handler.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),handler);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
}
}
客户端代码:
using System.Net; //新加的
using System.Net.Sockets; //新加的
using System.Threading; //新加的
namespace 异步客户端
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private IPAddress myIP = IPAddress.Parse("127.0.0.1");
private IPEndPoint MyServer;
private Socket sock;
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private void button1_Click(object sender, EventArgs e) //请求连接
{
try
{
myIP = IPAddress.Parse(textBox1.Text);
}
catch { MessageBox.Show("您输入的IP格式不正确,请重新输入"); }
try
{
MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.BeginConnect(MyServer,new AsyncCallback (ConnectCassback),sock);
connectDone.WaitOne();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}
private void ConnectCassback(IAsyncResult ar)
{
try
{
//获取状态
Socket client = (Socket)ar.AsyncState;
client.EndConnect(ar);
//自动发送数据
try
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");
//异步开始发送
sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
toolStripStatusLabel1.Text = " 主机 " + textBox1.Text + " 端口 " + textBox2.Text + " 建立连接!";
//定义线程
Thread thread = new Thread(new ThreadStart(targett));
//开始接收线程
thread.Start();
//设为终止
connectDone.Set();
}
catch { }
}
private void SendCallback(IAsyncResult ar)
{
try
{
//获取状态
Socket client = (Socket)ar.AsyncState;
//设为终止
sendDone.Set();
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
private void targett()
{
try
{
StateObject state = new StateObject();
state.workSocket = sock;
//开始异步接收数据
sock.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
//获取状态
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
//结束异步读数据,并获取结果
int bytesRead = client.EndReceive(ar);
//储存数据
state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
string aa = state.sb.ToString();
//清除state.sb
state.sb.Remove(0, aa.Length);
richTextBox1.AppendText(aa + "\r\n");
//读取未读数据
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch { }
}
private void button2_Click(object sender, EventArgs e) //发送信息
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(richTextBox2.Text);
//开始异步发送数据
sock.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),sock);
}
private void button3_Click(object sender, EventArgs e) //关闭连接
{
try
{
sock.Close();
toolStripStatusLabel1.Text = " 主机 " + textBox1.Text + " 端口 " + textBox2.Text + "断开连接!";
}
catch { MessageBox.Show("连接尚未建立,断开无效!"); }
}
}
}
这是服务器端和客户端的代码。
(1)我测试用的IP是127.0.0.1, 端口6688,每次点击客户端“关闭连接”时服务器端程序就退出。不知道为什么?
(2)当我想用自己电脑的IP时,点击服务器端的“开始监听”,总是在窗体下方显示“在其上下文中,该请求的地址无效”
--------------------编程问答-------------------- 或者当用自己电脑的IP时,随便用个端口号就出现异常“通常每个套接字的地址只能使用一次”(端口号是我用netstat在CMD的DOS环境中看到的),出现这个异常应该是端口冲突,那么我应该怎么样在程序中动态绑定一个可以用的端口呢? --------------------编程问答-------------------- 调用socket的close的时候会引发异常。你要捕获一下异常然后进行处理。
你那些回调方法里的EndXXX方法都加上捕获异常,然后做出处理。不然你close时引发的异常它不知道如何处理,所以就退出程序了。
你出现异常后,Socket监听的端口没有释放,所以再运行就出现“通常每个套接字的地址只能使用一次”的异常了。 --------------------编程问答-------------------- LS说的差不多了
然后使用ShurtDown方法,从容关闭
LZ最好看下一些别人写的通信程序,你的还是比较乱的
补充:.NET技术 , C#