异步Socket服务器与客户端

本文灵感来自Andre
Azevedo
 在CodeProject上面的一片文章,An
Asynchronous Socket Server and Client
,讲的是异步的Socket通信。

  • Socket连接(Socket Connection)

  • Socket服务(Socket Service)

  • 连接主机(Connection Host)

  • 加密与压缩(Encrypt与Compress)

  • 请求入队(Enqueuing Requests)

  • 确保发送和接收(Ensure send and recieve)

  • 检查消息头(Check message header)

  • 检查空闲连接(Checking idle connections)

  • 加密服务

  • SSL认证(SSL authentication)

  • 对称认证(Symmetric authentication)

  • 连接创建者(Connection Creator)

  • Socket服务器与Socket侦听者(SocketServer and SocketListener)

  • Socket服务器构造函数与方法(SocketServer constructor and methods)

  • Socket客户端与Socket连接者(SocketClient and SocketConnector)

  • Socket客户端构造函数与方法(SocketClient constructor and methods)

  • 应答演示项目(Echo Demo Project)

  • 主机(Hosts)

  • 服务(Services)

  • 结语(Conclusion)

  • 版本历史(History)

本文仅实现一个相对简单的异步Socket服务器与客户端通信示例。

首先需要说明如下2个问题

1.同步、异步、多线程是什么关系?答:同步是等待返回,相当于阻塞式;异步是不等待返回,是非阻塞式,可以用多线程实现。

2.有些异步方法有两种实现方式, 如BeginAccept()和AcceptAsync(), 这两个方法有什么区别呢?答:
 以 Begin 和 End 开头的方法是以 APM(Asynchronous Programming
Model)设计方法实现的异步操作, 以 Async 结尾的方法是利用称为 EAP (Event-based Asynchronous
Pattern) 的设计方法实现的异步操作。

界面简单如下:

主要代码如下:




using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

namespace Chatting

{

    public abstract class SocketFunc

    {

        //不管是服务端还是客户端, 建立连接后用这个Socket进行通信

        public Socket communicateSocket = null;

        //服务端和客户端建立连接的方式稍有不同, 子类会重载

        public abstract void Access(string IP, System.Action AccessAciton);

        //发送消息的函数

        public void Send(string message)

        {

            if (communicateSocket.Connected == false)

            {

                throw new Exception("还没有建立连接, 不能发送消息");

            }

            Byte[] msg = Encoding.UTF8.GetBytes(message);

            communicateSocket.BeginSend(msg,0, msg.Length, SocketFlags.None,

                ar => {

                

                }, null);

        }

        //接受消息的函数

        public void Receive(System.Action<string> ReceiveAction)

        {

            //如果消息超过1024个字节, 收到的消息会分为(总字节长度/1024 +1)条显示

            Byte[] msg = new byte[1024];

            //异步的接受消息

            communicateSocket.BeginReceive(msg, 0, msg.Length, SocketFlags.None,

                ar => {

                    //对方断开连接时, 这里抛出Socket Exception

                    //An existing connection was forcibly closed by the remote host

                        communicateSocket.EndReceive(ar);

                    ReceiveAction(Encoding.UTF8.GetString(msg).Trim(‘\0‘,‘ ‘));

                    Receive(ReceiveAction);

                }, null);

        }

    }

    public class ServerSocket:SocketFunc

    {

        //服务端重载Access函数

        public override void Access(string IP, System.Action AccessAciton)

        {

            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //本机预使用的IP和端口

            IPEndPoint serverIP = new IPEndPoint(IPAddress.Any, 9050);

            //绑定服务端设置的IP

            serverSocket.Bind(serverIP);

            //设置监听个数

            serverSocket.Listen(1);

            //异步接收连接请求

            serverSocket.BeginAccept(ar =>

                {

                    base.communicateSocket = serverSocket.EndAccept(ar);

                    AccessAciton();

                }, null);

        }

    }

    public class ClientSocket:SocketFunc

    {

        //客户端重载Access函数

        public override void Access(string IP, System.Action AccessAciton)

        {

            base.communicateSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            base.communicateSocket.Bind(new IPEndPoint(IPAddress.Any, 9051));

            

            //服务器的IP和端口

            IPEndPoint serverIP;

            try

            {

                serverIP = new IPEndPoint(IPAddress.Parse(IP), 9050);

            }

            catch

            {

                throw new Exception(String.Format("{0}不是一个有效的IP地址!", IP));

            }

            

            //客户端只用来向指定的服务器发送信息,不需要绑定本机的IP和端口,不需要监听

            try

            {

                base.communicateSocket.BeginConnect(serverIP, ar =>

                {

                    AccessAciton();

                }, null);

            }

            catch

            {

                throw new Exception(string.Format("尝试连接{0}不成功!", IP));

            }

        }

    }

}

相关的事件处理程序,如下:

效果,如下:

时间: 2024-11-09 16:07:14

异步Socket服务器与客户端的相关文章

python编写socket服务器和客户端

本次使用的主要模块是socket模块,在这个模块中可以找到socket()函数,该函数用于创建套接字对象.套接字也有自己的方法集,这些方法可以实现基于套接字的网络通信. socket()模块函数 要创建套接字,必须使用socket.socket()函数,语法如下: socket(socket_family,socket_type,protocol=0) 其中socket_family是AF_UNIX(基于文件)或AF_INET(面向网络),socket_type是SOCK_STREAM(TCP)

一个 Java 的 Socket 服务器和客户端通信的例子

http://blog.csdn.net/defonds/article/details/7971259 多个客户端对应一个服务端的通信的一个小例子.  服务端和客户端代码: public class Server { /** * 监听的端口 */ public static final int PORT = 12345; public static void main(String[] args) { System.out.println("服务器启动>>>>>&

Delhi socket服务器和客户端互操作

SOCKET TCP procedure idtcpsrvr1Execute(AThread: TIdPeerThread); procedure idtcpsrvr1Connect(AThread: TIdPeerThread); idtcpsrvr1: TIdTCPServer; idtcpclnt1: TIdTCPClient; client: 连接服务器->发送数据消息 //连接服务器 idtcpclnt1.Host:='127.0.0.1'; idtcpclnt1.Port:=168;

python socket 服务器和客户端

一.服务器端的实现: __author__ = socket threading tcplink(sock, addr):     (% addr)     sock.send()     :         data = sock.recv()         .sleep()         data data.decode() == :             sock.send((% data.decode()).encode())     sock.close()     (% add

Linux_C socket 服务器与客户端交互程序(输入小写转换为大写)

client.c 1 /* interactionSocket/client.c 2 * 实现终端与服务器端的交互式输入输出 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <unistd.h> 8 #include <sys/types.h> 9 #include <sys/socket.h> 10 #include &

c#异步Socket Tcp服务器实现

原创性申明 本文作者: 小竹zz  本文地址:http://blog.csdn.net/zhujunxxxxx 转载请注明出处. 介绍 我之前写过一篇IOCP的文章: http://blog.csdn.net/zhujunxxxxx/article/details/43573879 这个比异步socket性能好,因为它复用对象了. 在c#中微软已经提供了TcpListener和TcpClient来实现Tcp的通讯,这部分已经有人写了比较好的异步服务器代码 http://www.cnblogs.c

Windows 8 Metro 关于StreamSocket与原异步Socket

前一篇 <Windows 8 Metro 关于 StreamSocket MSDN示例阅读>我们基本懂得如何通过StreamSocket 做监听.连接.发送接收数据. 同时前一篇留下的几个疑问,我们在这里进行实验和解答. 在“原有的异步Socket”连接方式与现在WIN8 Metro App 的StreamSocket 如何通信呢? 首先解释下这里说的“原有的异步Socket” 是什么. 在await/async 关键字出现前,我们的Socket异步是依靠System.Net 以及 Syste

C#网络编程系列文章(五)之Socket实现异步UDP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 本文介绍 在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现.System.Net 命名空间中的所有其他网络访问类都建立在该套接字Socket实现之上,如TCPClient.TCPListener 和 UDPCl

Unity3d 游戏与C#服务器 异步Socket 交互 (一)

Unity3d中提供了Socket供开发者使用,语法和.net中的一致. 一般来说,对于手游客户端,分为两个线程,一个是GLES渲染,另一个就是Socket线程了. 文章转自(http://blog.csdn.net/huutu) 不论是服务器,还是客户端.其间的数据包的接收与发送,都是通过Socket. 比如客户端要登录,我们就新建一个Socket,Connect到帐号服务器.帐号服务器一直在等待客户端的连接,客户端连接进来之后就准备发送接收数据包了. 文章转自(http://blog.csd