110,536
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace AsyncTcpServer {
public partial class Form1 : Form {
public const int BUFFSIZE = 1024;
public Socket m_server;
public byte[] m_buffer = new byte[BUFFSIZE];
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
//从程序设计上来说,只有创建界面的主线程才能访问界面上的控件
//因为我们在OnReceive中访问了控件,所以这里设置成false
CheckForIllegalCrossThreadCalls = false;
// Create a TCP/IP socket.
m_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 9998);
try {
m_server.Bind(localEndPoint);
m_server.Listen(100);
//while (true)
//{
// allDone.Reset();
m_server.BeginAccept(
new AsyncCallback(AcceptCallback),
m_server);
// allDone.WaitOne();
//}
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
}
}
public void AcceptCallback(IAsyncResult ar) {
try {
//allDone.Set();
// Get the socket that handles the client request.
//Socket listener = (Socket)ar.AsyncState;
Socket handler = m_server.EndAccept(ar); //返回的是什么?服务器的socket????
m_server = handler;
handler.BeginReceive(m_buffer, 0, m_buffer.Length, 0,
new AsyncCallback(ReceiveCallback), handler);
} catch (Exception ex) {
m_server.BeginAccept(new AsyncCallback(AcceptCallback), m_server);
}
}
public void ReceiveCallback(IAsyncResult ar) {
String content = String.Empty;
// Read data from the client socket.
int bytesRead = m_server.EndReceive(ar);
string strData = Encoding.ASCII.GetString(m_buffer, 0, bytesRead);
try {
if (bytesRead > 0) {
if (strData.Equals("closeClient")) {
strData = "client has gotten out...";
}
lstContent.Items.Add(strData);
}
m_server.BeginReceive(m_buffer, 0, m_buffer.Length, 0,
new AsyncCallback(ReceiveCallback), m_server);
} catch (Exception ex) {
//MessageBox.Show(ex.ToString());
m_server.BeginAccept(new AsyncCallback(AcceptCallback), m_server);
}
}
private void Send(String data) {
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
m_server.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), m_server);
}
private void SendCallback(IAsyncResult ar) {
try {
// Complete sending the data to the remote device.
int bytesSent = m_server.EndSend(ar);
//handler.Shutdown(SocketShutdown.Both);
//handler.Close();
} catch (Exception e) {
MessageBox.Show(e.ToString());
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;
namespace AsyncTcpClient
{
public partial class Form1 : Form
{
public Socket m_client;
public EndPoint m_epServer;
public byte[] m_buffer;
public int port = 9998;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
m_epServer = new IPEndPoint(ipAddress, port);
m_client = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
m_client.BeginConnect(m_epServer,
new AsyncCallback(ConnectCallback), m_client);
}
catch (Exception ex)
{
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Complete the connection.
m_client.EndConnect(ar);
lstContent.Items.Add("Socket connected to "+
m_client.RemoteEndPoint.ToString());
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private void Receive()
{
try
{
// Begin receiving the data from the remote device.
m_client.BeginReceive(m_buffer, 0, m_buffer.Length, 0,
new AsyncCallback(ReceiveCallback), m_client);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Read data from the remote device.
int bytesRead = m_client.EndReceive(ar);
if (bytesRead > 0)
{
lstContent.Items.Add(Encoding.ASCII.GetString(m_buffer, 0, bytesRead));
}
m_client.BeginReceive(m_buffer, 0, m_buffer.Length, 0,
new AsyncCallback(ReceiveCallback), m_client);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private void Send(String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
m_client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), m_client);
}
private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
lstContent.Items.Add(String.Format("Sent {0} bytes to server.", bytesSent));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (txtMessage.Text != string.Empty)
{
Send(txtMessage.Text);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Send("closeClient");//发送关闭客户端指令
}
}
}
public void AcceptCallback(IAsyncResult ar) {
try {
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
handler.BeginReceive(m_buffer, 0, m_buffer.Length, 0,
new AsyncCallback(ReceiveCallback), handler);
listener.BeginAccept(new AsyncCallback(AcceptCallback), handler);
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
}
}
然后就晕了,listener和handler与m_server这三个Socket不一样吗?
在AcceptCallBack中调用BeginAccept的是m_server还是listener啊?
改成如上的代码后,没异常了,但是当客户端发送消息时,服务器就自动关闭了m_server.BeginAccept(new AsyncCallback(AcceptCallback),
m_server);
所以Socket listener = (Socket)ar.AsyncState;这句注释和不注释是一样的吧//while (true)
//{
// allDone.Reset();
m_server.BeginAccept(
new AsyncCallback(AcceptCallback),
m_server);
// allDone.WaitOne();
//}
把这里面的注释去掉就可以连接多个客户端了,AcceptCallback方法里面的注释也要去掉,catch部分添加注释,出现异常输出即可,不要自动重新等待连接。