异步Socket编写的一个简易的聊天室
异步Socket的一点心得,代码注释的很完善。希望对还不太熟悉Socket的网友有点帮助,哪怕是一点点就可以了。
不说了,先截图吧
不说了,先截图吧
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:";
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();
}