有tcp异步通信代码,是服务端和客户端分开的,想把服务端和客户端合在一起,但有很多疑问:
1.如果A、B二台机器通信,A、B都启动了服务端,这时候B向A发出连接请求,双方建立一个socket套接字.问题是这时如果A又向B发出连接请求,难道又要建立一个socket套接字?直接用第一个socket可以吗?如果可以,在许多机器通信的情况下,又如何判断A、B已经建立连接,不用重新建立?
下面把下载的代码贴出来,帮我提下修改意见,谢谢!server:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace qq
{
public partial class Form1 : Form
{
public class StateObject
{ public Socket workSocket = null; // Client socket.
public const int BufferSize = 1024; // Size of receive buffer.
public byte[] buffer = new byte[BufferSize]; // Receive buffer.
public StringBuilder sb = new StringBuilder(); // Received data string. public StateObject()
{
// TODO: 在此处添加构造函数逻辑
}
} 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); //通知正在等待待的线程已发生了事件 public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{ } 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; }
} #region 服务端接受连接,异步方式,向客户端发送‘准备完毕’信号,从客户端接收信号
private void targett()
{
while (true)
{
Done.Reset();//阻塞线程
sock.BeginAccept(new AsyncCallback(AcceptCallback), sock);
Done.WaitOne();//阻塞当前线程,直到等到一个System.Threading.WaitHandle
}
} 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 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.Remove(0, content.Length);
richTextBox1.AppendText(content + "\r\n");
tt.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } #endregion private void button2_Click(object sender, EventArgs e)
{
try
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(textBox3.Text + ">>>" + richTextBox2.Text + "\r\n");
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
richTextBox2.Clear();//////////////////////////////////////////////// }
catch (Exception ee) { MessageBox.Show(ee.Message); }
} private void SendCallback(IAsyncResult ar)
{
try
{
handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
// richTextBox2.Text = "go send";
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
} private void button3_Click(object sender, EventArgs e)
{
try
{
sock.Close();
toolStripStatusLabel1.Text = "主机" + textBox1.Text + "端口" + textBox2.Text + "监听停止!";
}
catch { MessageBox.Show("监听尚未开始,关闭无效!"); }
}
}
}
1.如果A、B二台机器通信,A、B都启动了服务端,这时候B向A发出连接请求,双方建立一个socket套接字.问题是这时如果A又向B发出连接请求,难道又要建立一个socket套接字?直接用第一个socket可以吗?如果可以,在许多机器通信的情况下,又如何判断A、B已经建立连接,不用重新建立?
下面把下载的代码贴出来,帮我提下修改意见,谢谢!server:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace qq
{
public partial class Form1 : Form
{
public class StateObject
{ public Socket workSocket = null; // Client socket.
public const int BufferSize = 1024; // Size of receive buffer.
public byte[] buffer = new byte[BufferSize]; // Receive buffer.
public StringBuilder sb = new StringBuilder(); // Received data string. public StateObject()
{
// TODO: 在此处添加构造函数逻辑
}
} 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); //通知正在等待待的线程已发生了事件 public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{ } 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; }
} #region 服务端接受连接,异步方式,向客户端发送‘准备完毕’信号,从客户端接收信号
private void targett()
{
while (true)
{
Done.Reset();//阻塞线程
sock.BeginAccept(new AsyncCallback(AcceptCallback), sock);
Done.WaitOne();//阻塞当前线程,直到等到一个System.Threading.WaitHandle
}
} 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 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.Remove(0, content.Length);
richTextBox1.AppendText(content + "\r\n");
tt.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } #endregion private void button2_Click(object sender, EventArgs e)
{
try
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(textBox3.Text + ">>>" + richTextBox2.Text + "\r\n");
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
richTextBox2.Clear();//////////////////////////////////////////////// }
catch (Exception ee) { MessageBox.Show(ee.Message); }
} private void SendCallback(IAsyncResult ar)
{
try
{
handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
// richTextBox2.Text = "go send";
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
} private void button3_Click(object sender, EventArgs e)
{
try
{
sock.Close();
toolStripStatusLabel1.Text = "主机" + textBox1.Text + "端口" + textBox2.Text + "监听停止!";
}
catch { MessageBox.Show("监听尚未开始,关闭无效!"); }
}
}
}
client:using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;namespace qqclient
{
public partial class Form1 : Form
{
public class StateObject
{
public Socket workSocket = null; // Client socket.
public const int BufferSize = 256; // Size of receive buffer.
public byte[] buffer = new byte[BufferSize]; // Receive buffer.
public StringBuilder sb = new StringBuilder();// Received data string. public StateObject()
{
// TODO: 在此处添加构造函数逻辑
}
} 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); public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{ } 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(ConnectCallback), sock);
connectDone.WaitOne();
}
catch (Exception ee) { MessageBox.Show(ee.Message); } } private void ConnectCallback(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 button2_Click(object sender, EventArgs e)
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(textBox3.Text + ">>>" + richTextBox2.Text + "\r\n"); sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
richTextBox2.Clear(); }
private void SendCallback(IAsyncResult ar)
{
try
{ Socket client = (Socket)ar.AsyncState;
client.EndSend(ar); //i add
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);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
string aa = state.sb.ToString();
state.sb.Remove(0, aa.Length);
richTextBox1.AppendText(aa + "cccc"+"\r\n"); }
catch
{ }
}
private void button3_Click(object sender, EventArgs e)
{
try
{
sock.Close();
toolStripStatusLabel1.Text = "与主机" + textBox1.Text + "端口" + textBox2.Text + "断开连接!";
}
catch { MessageBox.Show("连接尚未建立,断开无效!"); } }
}
}
你要实现相互通信那你客户端也要对服务端进行监听吧?
你可以在客户端也开个线程
方法是在你client代码的
try
{
MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.BeginConnect(MyServer, new AsyncCallback(ConnectCallback), sock);
connectDone.WaitOne();
这部分后面加采用异步的BeginReceive,
StateObject state = new StateObject();
state.workSocket = Sock;
Sock.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
这个的实现和你服务端的差不多,用来接收服务端的socket,不需要使用thread在服务端我用同步的send试验了一下可以发出去在
你server端的代码
handler = listener.EndAccept(ar); 利用这个handler 或者state.workSocket
你想怎么send就怎么send