c#实现简单控制台udp异步通信程序示例

实现客户端发送请求,服务器端响应机制

UDP客户端代码


代码如下:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Client
{
    class Program
    {
        //客户端 Socket对象
        private static Socket clientSocket;
        //服务器端 终点
        private static EndPoint epServer;
        //接收数据的字符数组
        private static byte[] receiveData;

public static void Main(string[] args)
        {
            //客户端Socket对象实例化
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //设置服务器端IP地址和对应端口
            IPEndPoint server = new IPEndPoint(IPAddress.Parse("192.168.1.165"), 11000);
            //实例化服务器端 终点
            epServer = (EndPoint)server;
            string msg;     //要发送的消息
            byte[] sendData;    //要发送的字符串
            while (true) {
                msg = Console.ReadLine();   //输入要发送的消息
                if (msg == "exit") break;   //当输入“exit”时,退出客户端程序
                //将消息通过ASCII编码转换为字符数组,
                //如果要发送汉字或其他特殊符号,可以采用UTF-8
                sendData = Encoding.ASCII.GetBytes(msg);   
                //开始异步发送消息
                //参数:sendData           要发送的数据
                //参数:0:                 要发送数据的起始位置
                //参数:sendData.Length:   要发送数据的字节数
                //参数:SocketFlags.None:  按位组合方式
                //参数:epServer:          接收方设备(包含IP和端口)
                //参数:new AsyncCallback(SendData):   委托
                //参数:null:          请求的状态信息
                clientSocket.BeginSendTo(sendData, 0, sendData.Length, SocketFlags.None,
                    epServer, new AsyncCallback(SendData), null);
                //实例化接收数据的字符数组
                //若在声明时已经初始化,此处依然要进行重新初始化
                //当上次接收的数据长度大于本次,则该数组里包含上次接收的残留数据
                //比如:上次接收“你个小逗逼”。本次接收“开玩笑”。
                //则数组中的数据为:“开玩笑逗逼”。
                receiveData = new byte[1024];
                //开始异步接收消息
                //参数部分与异步发送部分对应,基本一致
                clientSocket.BeginReceiveFrom(receiveData, 0, receiveData.Length, SocketFlags.None,
                    ref epServer, new AsyncCallback(ReceiveData), null);
            }
        }

//异步发送消息的委托函数
        private static void SendData(IAsyncResult iar)
        {
            //完成异步发送
            clientSocket.EndSend(iar);
        }

//异步接收消息的委托函数
        private static void ReceiveData(IAsyncResult iar)
        {
            //完成异步接收  recv 表示接收到的字节数
            int recv = clientSocket.EndReceive(iar);
            //将接收到的数据打印出来
            Console.WriteLine("Server: " + Encoding.ASCII.GetString(receiveData, 0, recv));
        }

}
}

UDP服务器端代码

代码如下:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    class AsyncUdpServer
    {
        //服务器端Socket对象
        private static Socket serverSocket;
        //接收数据的字符数组
        private static byte[] receiveData = new byte[1024];

public static void Main(string[] args)
        {
            //实例化服务器端Socket对象
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //服务器端的IP和端口,IPAddress.Any实际是:0.0.0.0,表示任意,基本上表示本机IP
            IPEndPoint server = new IPEndPoint(IPAddress.Any, 11000);
            //Socket对象跟服务器端的IP和端口绑定
            serverSocket.Bind(server);
            //客户端的IP和端口,端口 0 表示任意端口
            IPEndPoint clients = new IPEndPoint(IPAddress.Any, 0);
            //实例化客户端 终点
            EndPoint epSender = (EndPoint)clients;
            //开始异步接收消息  接收后,epSender存储的是发送方的IP和端口
            serverSocket.BeginReceiveFrom(receiveData, 0, receiveData.Length, SocketFlags.None,
                ref epSender, new AsyncCallback(ReceiveData), epSender);
            Console.WriteLine("Listening...");
            Console.ReadLine();
        }

private static void SendData(IAsyncResult iar)
        {
            serverSocket.EndSend(iar);
        }

private static void ReceiveData(IAsyncResult iar)
        {
            //客户端的IP和端口,端口 0 表示任意端口
            IPEndPoint client = new IPEndPoint(IPAddress.Any, 0);
            //实例化客户端 终点
            EndPoint epSender = (EndPoint)client;
            //结束异步接收消息  recv 表示接收到的字符数
            int recv = serverSocket.EndReceiveFrom(iar, ref epSender);           
            //将接收到的数据打印出来,发送方采用什么编码方式,此处就采用什么编码方式 转换成字符串
            Console.WriteLine("Client:" + Encoding.ASCII.GetString(receiveData, 0, recv));
            //定义要发送回客户端的消息,采用ASCII编码,
            //如果要发送汉字或其他特殊符号,可以采用UTF-8           
            byte[] sendData = Encoding.ASCII.GetBytes("hello");
            //开始异步发送消息  epSender是上次接收消息时的客户端IP和端口信息
            serverSocket.BeginSendTo(sendData, 0, sendData.Length, SocketFlags.None,
                epSender, new AsyncCallback(SendData), epSender);
            //重新实例化接收数据字节数组
            receiveData = new byte[1024];
            //开始异步接收消息,此处的委托函数是这个函数本身,递归
            serverSocket.BeginReceiveFrom(receiveData, 0, receiveData.Length, SocketFlags.None,
                ref epSender, new AsyncCallback(ReceiveData), epSender);
        }

}
}

(0)

相关推荐

  • c#取得控制台应用程序根目录

    1.取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径方法2.AppDomain.CurrentDomain.BaseDirectory 获取基目录,它由程序集冲突解决程序用来探测程序集 2.取得Web应用程序的根目录方法 方法1.HttpRuntime.AppDomainAppPath.ToString();//获取承载在当前应用程序域中的应用程序的应用程序目录的物理驱动器路径.用于App_Data中获取方法2

  • ASP.NET(C#)中操作SQLite数据库实例

    要想在ASP.NET项目中使用SQLite数据库,先需下载一个ADO.NET 2.0 SQLite Data Provider,下载地址为:http://sourceforge.net/project/showfiles.php?group_id=132486&package_id=145568,下载后安装完毕后,该安装程序自动在在系统注册(即可在"添加引用"中看到所安装的Provider).     然后,在项目中添加上图所选项即可. aspx页面仅包含一按钮btnTest,

  • C#中使用SQLite数据库的方法介绍

    [SQLite管理工具简介] 推荐以下2款: Navicat for SQLite:功能非常强大,几乎包含了数据库管理工具的所有必需功能,操作简单,容易上手.唯一的缺点是不能打开由System.Data.SQLite.dll加密过的数据库. Database.Net:台湾人用.net开发的全能数据库管理工具,可以管理多种数据库,包括MSSQL.MYSQL.IBM DB2.Oracle.Access.Excel.OleDb.Odbc等十多种数据库(或数据接口),功能没有Navicat那么多,只包含

  • C#控制台带参数程序源码编写实例讲解

    像ipconfig /all 这样的CMD命令想必大家都知道,但是很多童鞋可能不知道怎么写这样的控制台带参数的程序,其实很简单,我们先看建立项目的默认代码: 复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace _1 { class Program { static void Main(string[] args) { } } } 好了.

  • C#操作SQLite方法实例详解

    本文实例讲述了C#操作SQLite方法.分享给大家供大家参考.具体分析如下: 地址: System.Data.Sqlite入手... 首先import/using: 复制代码 代码如下: using System.Data.SQLite; Connection和Command: private SQLiteConnection conn; private SQLiteCommand cmd; 连接db: conn = new SQLiteConnection("Data Source=c:\\t

  • C#控制台基础 list<>初始化的两种方法

    代码一. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { List<int> list1 = new List<int> { 1, 2,

  • C#创建SQLite控制台应用程序详解

    一.开发环境 操作系统:Windows 10 X64 开发环境:VS2015 编程语言:C# .NET版本:.NET Framework 4.0 目标平台:X86 二.前言 之前使用的是软件的Access来创建基于本地的数据库软件,发现在使用过程中,发现Access比较耗内存,运行速度比SQLite稍微慢,另外一个最重要的是Access加密的文件容易被破解,因此,现在转向使用SQLite来代替Access. 三.SQLite的下载 1.由于是基于.NET的C#编程,需下载System.Data.

  • C#控制台程序中处理2个关闭事件的代码实例

    应用场景 我们开发的控制台应用,在运行阶段很有可能被用户Ctrl+C终止或是被用户直接关闭.如果我们不希望用户通过Ctrl+C终止我们的程序,就需要对Ctrl+C或关闭事件作处理. 处理方法 在.net平台下Console类有个CancelKeyPress事件可以处理Ctrl+C,不过对于直接关闭控制台应用,这种处理就无能为力了. 不过Windows API中有个SetConsoleCtrlHandler函数可以处理这两种关闭事件. C#处理代码如下: 复制代码 代码如下: static cla

  • C#控制台输出进度和百分比的实例代码

    复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 {     class Program     {         static void Main(string[] args)         {             bool isBreak = false;             C

  • C#中实现在32位、64位系统下自动切换不同的SQLite dll文件

    直接上代码: using System; using System.Collections.Generic; using System.Windows.Forms; using System.Management; using System.IO; namespace SqliteAuto { static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main

随机推荐