基于C#的异步Socket程序(TCP)
2017-12-03 19:58
555 查看
今天我门将通过一个多人聊天的例子来说明异步Socket程序。
没有基础的可以看一下之前的同步Socket程序。
地址:http://blog.csdn.net/YongshuangZhao/article/details/78696718
1.代码如下:
服务端代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Collections.Generic;
namespace AsyncTCPServer
{
//客户端连接类
public class Connect
{
//与客户端连接的套接字
public Socket socket;
//缓冲区大小
public const int BUFFER_SIZE=1024;
//读缓冲区
public byte[] readBuff=new byte[BUFFER_SIZE];
//当前缓冲区大小
public int buffCount=0;
//是否被使用
public bool isUse=false;
public Connect ()
{
readBuff=new byte[BUFFER_SIZE];
}
//初始化
//初始化方法,在启用一个连接时会调用该方法,从而给一些变量赋值
public void Init(Socket socket){
this.socket = socket;
isUse = true;
buffCount = 0;
}
//缓冲区剩余的字节数
public int BuffRemain(){
return BUFFER_SIZE - buffCount;
}
//获取客户端IP地址和端口
public string GetAdress(){
if (!isUse) {
return "无法获取地址";
}
return socket.RemoteEndPoint.ToString ();
}
//关闭
public void Close(){
if (!isUse) {
return;
}
Console.WriteLine ("[断开连接]" + GetAdress ());
socket.Close ();
isUse = false;
}
}
}
没有基础的可以看一下之前的同步Socket程序。
地址:http://blog.csdn.net/YongshuangZhao/article/details/78696718
1.代码如下:
服务端代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Collections.Generic;
namespace AsyncTCPServer
{
//客户端连接类
public class Connect
{
//与客户端连接的套接字
public Socket socket;
//缓冲区大小
public const int BUFFER_SIZE=1024;
//读缓冲区
public byte[] readBuff=new byte[BUFFER_SIZE];
//当前缓冲区大小
public int buffCount=0;
//是否被使用
public bool isUse=false;
public Connect ()
{
readBuff=new byte[BUFFER_SIZE];
}
//初始化
//初始化方法,在启用一个连接时会调用该方法,从而给一些变量赋值
public void Init(Socket socket){
this.socket = socket;
isUse = true;
buffCount = 0;
}
//缓冲区剩余的字节数
public int BuffRemain(){
return BUFFER_SIZE - buffCount;
}
//获取客户端IP地址和端口
public string GetAdress(){
if (!isUse) {
return "无法获取地址";
}
return socket.RemoteEndPoint.ToString ();
}
//关闭
public void Close(){
if (!isUse) {
return;
}
Console.WriteLine ("[断开连接]" + GetAdress ());
socket.Close ();
isUse = false;
}
}
}
using System; using System.Net; using System.Net.Sockets; using System.Collections; using System.Collections.Generic; namespace AsyncTCPServer { //该类包含一个Connect类型的对象池(数组),用于维护客户端连接。 public class Server { //监听嵌套字 public Socket listenfd; //客户端连接 public Connect[] connects; //最大连接数 public int maxConnectCount=50; //开启服务器 public void Start(string host,int port){ //连接池 connects=new Connect[maxConnectCount]; for (int i = 0; i < maxConnectCount; i++) { connects [i] = new Connect (); } //Socket连接的流程 //socket listenfd =new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //Bind IPAddress ipAdr=IPAddress.Parse(host); IPEndPoint ipEp = new IPEndPoint (ipAdr, port); listenfd.Bind (ipEp); //Listen listenfd.Listen(maxConnectCount); //Accept listenfd.BeginAccept(AcceptCb,null); Console.WriteLine ("[服务器]启动成功"); } //获取连接池索引,返回负数表示获取失败 public int NewIndex(){ if (connects == null) { return -1; } for (int i = 0; i < connects.Length; i++) { if (connects [i] == null) { connects [i] = new Connect (); return i; } else if (connects [i].isUse == false) { return i; } } return -1; } //Accept是BeginAccept的回调函数,它成立了如下3件事情 //(1)给新的连接分配connect //(2)异步接收客户端数据 //(3)再次调用BeginAccept实现循环 //Accept回调 private void AcceptCb(IAsyncResult ar){ try{ Socket socket=listenfd.EndAccept(ar); int index=NewIndex(); if(index<0){ socket.Close(); Console.WriteLine("[警告]连接已满"); }else{ Connect connect=connects[index]; connect.Init(socket); string adr=connect.GetAdress(); Console.WriteLine("客户端["+adr+"]connect池ID:"+index); connect.socket.BeginReceive(connect.readBuff,connect.buffCount,connect.BuffRemain(),SocketFlags.None,ReceiveCb,connect); } listenfd.BeginAccept(AcceptCb,null); }catch(Exception e){ Console.WriteLine ("AcceptCb失败:" + e.Message); } } //ReceiveCb是BeginReceive的回调函数,它处理了3件事情 //(1)接收并处理消息,因为有多个客户端,服务端收到消息后,要把它转发给所有人 //(2)如果收到客户端关闭连接的信号(count==0),则断开连接 //(3)继续调用BeginReceive接收下一个数据 //Receive回调 private void ReceiveCb(IAsyncResult ar){ Connect connect = (Connect)ar.AsyncState; try{ int count=connect.socket.EndReceive(ar); //关闭信号 if(count<=0){ Console.WriteLine("收到["+connect.GetAdress()+"]断开连接"); connect.Close(); return; } //数据处理 string str=System.Text.Encoding.UTF8.GetString(connect.readBuff,0,count); Console.WriteLine("收到["+connect.GetAdress()+"]数据:"+str); str=connect.GetAdre a62b ss()+":"+str; byte[] bytes=System.Text.Encoding.Default.GetBytes(str); //广播 for(int i=0;i<connects.Length;i++){ if(connects[i]==null){ continue; } if(!connects[i].isUse){ continue; } Console.WriteLine("将消息转播给"+connects[i].GetAdress()); connects[i].socket.Send(bytes); } //继续接收 connect.socket.BeginReceive(connect.readBuff,connect.buffCount,connect.BuffRemain(),SocketFlags.None,ReceiveCb,connect); }catch(Exception e){ Console.WriteLine ("AcceptCb失败:" + e.Message); Console.WriteLine ("收到[" + connect.GetAdress () + "]断开连接"); connect.Close (); } } } }异步服务端示意图如下:
using System; using System.Net; using System.Net.Sockets; using System.Collections; using System.Collections.Generic; namespace AsyncTCPServer { class MainClass { public static void Main (string[] args) { Server server = new Server (); server.Start ("127.0.0.1",1234); while (true) { string str = Console.ReadLine (); switch (str) { case "quit": return; } } } } }2.客户端代码如下:
using System; using System.Net; using System.Net.Sockets; namespace AsyncTCPClient { public class Client { //Socket和接收缓存区 private Socket socket; private byte[] readBuff; private const int BUFFER_SIZE = 1024; //启动客户端 public void Start(string host,int port){ //Socket socket = new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //Connect socket.Connect(host,port); //Receive readBuff=new byte[BUFFER_SIZE]; socket.BeginReceive (readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null); } //接收回调 private void ReceiveCb(IAsyncResult ar){ try { //count是接收数据的大小 int count = socket.EndReceive (ar); //数据处理 string str = System.Text.Encoding.UTF8.GetString (readBuff, 0, count); Console.WriteLine(str); //继续接收 socket.BeginReceive (readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null); } catch (Exception e) { Console.WriteLine (e.Message); Console.WriteLine ("连接已断开"); socket.Close (); } } //发送回调 public void Send(string str){ byte[] bytes = System.Text.Encoding.Default.GetBytes (str); try { socket.Send (bytes); } catch { } } } }
using System; using System.Net; using System.Net.Sockets; namespace AsyncTCPClient { class MainClass { public static void Main (string[] args) { Client client = new Client (); client.Start ("127.0.0.1", 1234); Console.ReadKey (); while (true) { string str = Console.ReadLine (); if (str == "quit") { return; } else { client.Send (str); } } } } }3.运行结果如下:
相关文章推荐
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的同步Socket程序(TCP)
- 基于C#的Socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现 ,包含服务器端与客户端源代码
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步实现
- 基于C#的socket编程的TCP异步的实现代码
- C#的Socket程序(TCP)
- VC面向对象的方式 写一个基于TCP的 客户端服务端程序 (SOCKET)
- 一个基于VB.net的异步Socket网络TCP通信可防止任意一端意外终止TCP连接的类,。
- [转]在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)
- 基于Linux的Socket编程之TCP全双工Server-Client聊天程序
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)