异步Socket的一点心得,代码注释的很完善。希望对还不太熟悉Socket的网友有点帮助,哪怕是一点点就可以了。
不说了,先截图吧
不说了,先截图吧
![](https://i-blog.csdnimg.cn/blog_migrate/51b9099a05d530ff4abbb88f0671576c.jpeg)
using
System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Windows.Forms;
namespace WindowsApplication1
{
class MySocket
{
private string ip = null ;
private int port = 0 ;
public Socket TcpSocket = null ; // 这里定义Public级别是为在类外访问
public byte [] bb = new byte [ 1024 ];
int num = 0 ;
public TextBox tx;
public MySocket( string ip, int port)
{
this .ip = ip;
this .port = port;
}
public string Ip
{
get { return ip; }
set { ip = value; }
}
public int Port
{
get { return port; }
set { port = value; }
}
/// <summary>
/// 设置终结点,并用异步来接收传过来的Socket对象
/// </summary>
public void GetSocket()
{
// 用Parse方法转换字符
IPAddress ipname = IPAddress.Parse(ip);
// 设置终结点,为以后Socket绑定做准备
IPEndPoint iphost = new IPEndPoint(ipname, Port);
// 我用Tcp协议,所以用SocketType.Stream,如果你用Udp,那么请用SocketType.Dgram
Socket mysock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mysock.Bind(iphost); // 绑定,这是Socket基本用法
mysock.Listen( 100 ); // 开始监听
// 这个异步表示如果mysock一旦发现有客户断连接,那么异步方法将会被立即调用
// 有很多网友称之为“启动后不管”
mysock.BeginAccept( new AsyncCallback(Shu), mysock);
}
public void Shu(IAsyncResult e)
{
Socket s = (Socket)e.AsyncState; // 这里是异步的通用做法,用异步接口的AsyncState返回自身
TcpSocket = s.EndAccept(e); // 这里是接收的真正的异步Socket对象
// 下面继续用异步接收信息,之所以用异步接收,是因为程序
// 运行在UI里面,以妨程序出现假死状态,后面我将会用线程来控制这个问题
AsyncCallback mm = new AsyncCallback(GetShu);
TcpSocket.BeginReceive(bb, 0 , bb.Length, SocketFlags.None, mm, TcpSocket); // 这里把自身做为参数给下个异步方法调用
s.BeginAccept( new AsyncCallback(Shu), s);
}
// 这里创建代表是用于在UI线程上设置TextBox的值,因为线程Id值不一样,所以必须用BeginInvoke设置
public delegate void MyDeleTe( string txt);
public void SetTxt( string txt)
{
if (tx.InvokeRequired) // 这里其实是多余的,但它可以防止不是同一线城的设置
{
tx.BeginInvoke( new MyDeleTe(SetTxt), txt);
}
else
{
tx.Text += " \r\n " + txt;
}
}
public void GetShu(IAsyncResult e)
{
Socket list = (Socket)e.AsyncState;
// 我想解释一下为什么EndReceive(e);后的返回对象都不一样
// 比如Socket返回的是Socket对象,而接收信息返回的是int对象呢?
// 因为那是因为调用这个方法返回的值。比如Receive方法返回是int,所以异步也返回int.
num = list.EndReceive(e);
string message = " Client say:
"
;
if (num > 0 )
{
message += Encoding.ASCII.GetString(bb, 0 , num); // message是返回的Client发来的信息
tx.BeginInvoke( new MyDeleTe(SetTxt), message.ToString());
}
}
}
}
由于时间关系,只做了个服务器端类异步程序,代码如上所示。调用非常简单,只需
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Windows.Forms;
namespace WindowsApplication1
{
class MySocket
{
private string ip = null ;
private int port = 0 ;
public Socket TcpSocket = null ; // 这里定义Public级别是为在类外访问
public byte [] bb = new byte [ 1024 ];
int num = 0 ;
public TextBox tx;
public MySocket( string ip, int port)
{
this .ip = ip;
this .port = port;
}
public string Ip
{
get { return ip; }
set { ip = value; }
}
public int Port
{
get { return port; }
set { port = value; }
}
/// <summary>
/// 设置终结点,并用异步来接收传过来的Socket对象
/// </summary>
public void GetSocket()
{
// 用Parse方法转换字符
IPAddress ipname = IPAddress.Parse(ip);
// 设置终结点,为以后Socket绑定做准备
IPEndPoint iphost = new IPEndPoint(ipname, Port);
// 我用Tcp协议,所以用SocketType.Stream,如果你用Udp,那么请用SocketType.Dgram
Socket mysock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mysock.Bind(iphost); // 绑定,这是Socket基本用法
mysock.Listen( 100 ); // 开始监听
// 这个异步表示如果mysock一旦发现有客户断连接,那么异步方法将会被立即调用
// 有很多网友称之为“启动后不管”
mysock.BeginAccept( new AsyncCallback(Shu), mysock);
}
public void Shu(IAsyncResult e)
{
Socket s = (Socket)e.AsyncState; // 这里是异步的通用做法,用异步接口的AsyncState返回自身
TcpSocket = s.EndAccept(e); // 这里是接收的真正的异步Socket对象
// 下面继续用异步接收信息,之所以用异步接收,是因为程序
// 运行在UI里面,以妨程序出现假死状态,后面我将会用线程来控制这个问题
AsyncCallback mm = new AsyncCallback(GetShu);
TcpSocket.BeginReceive(bb, 0 , bb.Length, SocketFlags.None, mm, TcpSocket); // 这里把自身做为参数给下个异步方法调用
s.BeginAccept( new AsyncCallback(Shu), s);
}
// 这里创建代表是用于在UI线程上设置TextBox的值,因为线程Id值不一样,所以必须用BeginInvoke设置
public delegate void MyDeleTe( string txt);
public void SetTxt( string txt)
{
if (tx.InvokeRequired) // 这里其实是多余的,但它可以防止不是同一线城的设置
{
tx.BeginInvoke( new MyDeleTe(SetTxt), txt);
}
else
{
tx.Text += " \r\n " + txt;
}
}
public void GetShu(IAsyncResult e)
{
Socket list = (Socket)e.AsyncState;
// 我想解释一下为什么EndReceive(e);后的返回对象都不一样
// 比如Socket返回的是Socket对象,而接收信息返回的是int对象呢?
// 因为那是因为调用这个方法返回的值。比如Receive方法返回是int,所以异步也返回int.
num = list.EndReceive(e);
string message = " Client say:
![](https://www.cnblogs.com/Images/dot.gif)
if (num > 0 )
{
message += Encoding.ASCII.GetString(bb, 0 , num); // message是返回的Client发来的信息
tx.BeginInvoke( new MyDeleTe(SetTxt), message.ToString());
}
}
}
}
private
void
Form1_Load(
object
sender, EventArgs e)
{
string ip = " 127.0.0.1 " ;
int port = 2000 ;
MySocket mm = new MySocket(ip, port);
mm.tx = txtserver;
mm.GetSocket();
}
欢迎大家讨论.
{
string ip = " 127.0.0.1 " ;
int port = 2000 ;
MySocket mm = new MySocket(ip, port);
mm.tx = txtserver;
mm.GetSocket();
}