通过异步方式发送和接收数据(tcp异步收发数据)

服务端

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TcpTest2
{
    public partial class Form1 : Form
    {
        bool isExit = false;
        System.Collections.ArrayList clientList = new System.Collections.ArrayList();
        TcpListener listener;
        delegate void SetListBoxCallBack(string str);
        SetListBoxCallBack setListCallBack;
        delegate void SetRecvBoxCallBack(string str);
        SetRecvBoxCallBack setRecvBoxCallBack;
        delegate void SetComboBoxCallBack(string str);
        SetComboBoxCallBack setComboBoxCallBack;
        delegate void RemoveComboBoxCallBack(DataReadWrite drw);
        RemoveComboBoxCallBack removeComboBoxCallBack;
        ManualResetEvent allDone = new ManualResetEvent(false);//通知一个或多个正在等待的线程已发生事件

        public Form1()
        {
            InitializeComponent();
            setListCallBack = new SetListBoxCallBack(setListBox);
            setRecvBoxCallBack = new SetRecvBoxCallBack(this.setRichBox);
            setComboBoxCallBack = new SetComboBoxCallBack(this.setComboBox);
            removeComboBoxCallBack = new RemoveComboBoxCallBack(this.removeComboBoxItem);
            button2.Enabled = false;
        }
        private void setListBox(string str)
        {
            listBox1.Items.Add(str);
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            listBox1.ClearSelected();
        }
        private void setRichBox(string str)
        {
            richTextBox1.AppendText(str);
        }
        private void setComboBox(object obj)
        {
            comboBox1.Items.Add(obj);
        }
        private void removeComboBoxItem(DataReadWrite drw)
        {
            int index = clientList.IndexOf(drw);
            comboBox1.Items.Remove(index);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(AcceptConn));//新建线程建立侦听
            t.Start();
            button1.Enabled = false;
            button2.Enabled = true;
        }
        private void AcceptConn()
        {
            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
            listener = new TcpListener(ips[0], 51888);
            listener.Start();
            while (isExit == false)
            {
                allDone.Reset();//将事件状态设置为非终止状态
                AsyncCallback callback = new AsyncCallback(acceptTcpClientCallBack);
                listBox1.Invoke(setListCallBack, "开始等待连接");
                listener.BeginAcceptTcpClient(callback, listener);//开始一个异步操作,来接受一个传入的连接尝试
                allDone.WaitOne();//阻止当前线程,直到allDone.Set()之后继续运行
            }
        }
        /// <summary>
        /// 接收到一个请求,此方法运行在异步线程上
        /// </summary>
        /// <param name="iar"></param>
        private void acceptTcpClientCallBack(IAsyncResult iar)
        {
            allDone.Set();
            TcpListener listener = (TcpListener)iar.AsyncState;
            TcpClient client = listener.EndAcceptTcpClient(iar);//异步接受传入的连接并创建新的TcpClient来处理远程主机通信
            listBox1.Invoke(setListCallBack, "已接受客户连接:" + client.Client.RemoteEndPoint);
            comboBox1.Invoke(setComboBoxCallBack, client.Client.RemoteEndPoint.ToString());
            DataReadWrite drw = new DataReadWrite(client);
            clientList.Add(drw);
            SendString(drw, "服务器已接受连接");
            drw.netStream.BeginRead(drw.read, 0, drw.read.Length, new AsyncCallback(readCallBack), drw);//开始异步读取数据
        }
        /// <summary>
        /// 发送字符串
        /// </summary>
        /// <param name="drw"></param>
        /// <param name="str"></param>
        private void SendString(DataReadWrite drw, string str)
        {
            drw.write = Encoding.UTF8.GetBytes(str + "\r\n");
            drw.netStream.BeginWrite(drw.write, 0, drw.write.Length, new AsyncCallback(SendCallBack), drw);//开始向流异步写入数据
            drw.netStream.Flush();
            listBox1.Invoke(setListCallBack, string.Format("向{0}发送{1}", drw.client.Client.RemoteEndPoint, str));
        }
        /// <summary>
        /// 发送字符串完毕
        /// </summary>
        /// <param name="iar"></param>
        private void SendCallBack(IAsyncResult iar)
        {
            DataReadWrite drw = (DataReadWrite)iar.AsyncState;
            drw.netStream.EndWrite(iar);//异步写入数据结束
        }
        /// <summary>
        /// 接收字符串
        /// </summary>
        /// <param name="iar"></param>
        private void readCallBack(IAsyncResult iar)
        {
            DataReadWrite drw = (DataReadWrite)iar.AsyncState;
            int recv = drw.netStream.EndRead(iar);//异步读取结束
            richTextBox1.Invoke(setRecvBoxCallBack, string.Format("来自{0}:{1}", drw.client.Client.RemoteEndPoint, Encoding.UTF8.GetString(drw.read, 0, recv)));
            if (isExit == false)
            {
                drw.InitReadArr();
                drw.netStream.BeginRead(drw.read, 0, drw.read.Length, readCallBack, drw);//无限循环的读取下去
            }
        }
        /// <summary>
        /// 断开连接,没写代码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            int index = comboBox1.SelectedIndex;
            if (index != -1)
            {
                DataReadWrite drw = (DataReadWrite)clientList[index];
                SendString(drw, richTextBox2.Text);
                richTextBox2.Clear();
            }
        }
    }
/// <summary>
/// 数据输入输出基础类
/// </summary>
    public class DataReadWrite
    {
        public TcpClient client;
        public NetworkStream netStream;
        public byte[] read;
        public byte[] write;
        public DataReadWrite(TcpClient client)
        {
            this.client = client;
            netStream = client.GetStream();//获取用于发送和接受数据的流
            read = new byte[client.ReceiveBufferSize];
            write = new byte[client.SendBufferSize];
        }
        public void InitReadArr()
        {
            read = new byte[client.ReceiveBufferSize];
        }
        public void InitWriterArr()
        {
            write = new byte[client.SendBufferSize];
        }
    }
}

客户端

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TcpTest
{
    public partial class Form1 : Form
    {
        bool isExit = false;
        delegate void SetListBoxCallBack(string str);
        SetListBoxCallBack setListCallBack;
        delegate void SetRecvBoxCallBack(string str);
        SetRecvBoxCallBack setRecvBoxCallBack;
        TcpClient client;
        NetworkStream netStream;
        ManualResetEvent allDone = new ManualResetEvent(false);//通知一个或多个正在等待的线程已发生事件

        public Form1()
        {
            InitializeComponent();
            setListCallBack = new SetListBoxCallBack(setListBox);
            setRecvBoxCallBack = new SetRecvBoxCallBack(this.setRecvBox);
        }
        private void setListBox(string str)
        {
            listBox1.Items.Add(str);
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            listBox1.ClearSelected();
        }
        private void setRecvBox(string str)
        {
            richTextBox1.AppendText(str);
        }
        /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            client = new TcpClient(AddressFamily.InterNetwork);
            AsyncCallback requestCallBack = new AsyncCallback(this.requestCallBack);//引用在相应异步操作完成时调用的方法
            allDone.Reset();//将事件线程设置为非终止状态
            client.BeginConnect(IPAddress.Parse(textBox1.Text.Trim()), 51888, requestCallBack, client);
            listBox1.Invoke(setListCallBack, string.Format("本地终结点:{0}", client.Client.LocalEndPoint));
            listBox1.Invoke(setListCallBack, string.Format("开始与服务器连接"));
            allDone.WaitOne();//阻止当前线程,直到allDone.Set()之后继续运行
        }

        /// <summary>
        /// 连接服务器成功
        /// </summary>
        /// <param name="iar">表示异步操作的状态</param>
        private void requestCallBack(IAsyncResult iar)
        {
            allDone.Set();
            client = (TcpClient)iar.AsyncState;
            client.EndConnect(iar);
            listBox1.Invoke(setListCallBack, string.Format("与服务器{0}连接成功", client.Client.RemoteEndPoint));
            netStream = client.GetStream();
            DataRead dr = new DataRead(netStream, client.ReceiveBufferSize);//client.ReceiveBufferSize接收缓冲区的大小
            netStream.BeginRead(dr.msg, 0, dr.msg.Length, new AsyncCallback(readCallBack), dr);//开始接受数据
        }
        /// <summary>
        /// 接收数据完成
        /// </summary>
        /// <param name="iar"></param>
        private void readCallBack(IAsyncResult iar)
        {
            DataRead dr = (DataRead)iar.AsyncState;
            int recv = dr.netStream.EndRead(iar);
            richTextBox2.Invoke(setRecvBoxCallBack, Encoding.UTF8.GetString(dr.msg, 0, recv));
            if (isExit == false)
            {
                dr = new DataRead(netStream, client.ReceiveBufferSize);//此处有些不妥,可参照服务端的做法
                netStream.BeginRead(dr.msg, 0, dr.msg.Length, this.readCallBack, dr);//无限的接收下去
            }

        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            sendString(richTextBox2.Text);
            richTextBox2.Clear();
        }
        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="str"></param>
        private void sendString(string str)
        {
            byte[] bytesdata = Encoding.UTF8.GetBytes(str + "\r\n");
            netStream.BeginWrite(bytesdata, 0, bytesdata.Length, new AsyncCallback(sendCallBack), netStream);
            netStream.Flush();
        }
        /// <summary>
        /// 异步发送数据完成
        /// </summary>
        /// <param name="iar"></param>
        private void sendCallBack(IAsyncResult iar)
        {
            netStream.EndWrite(iar);

        }
    }
    /// <summary>
    /// 接收数据基础类
    /// </summary>
    public class DataRead
    {
        public NetworkStream netStream;
        public byte[] msg;
        public DataRead(NetworkStream ns, int buffersize)
        {
            this.netStream = ns;
            this.msg = new byte[buffersize];
        }
    }
}
时间: 2024-11-04 19:30:19

通过异步方式发送和接收数据(tcp异步收发数据)的相关文章

Android imageloader异步方式显示图片的

问题描述 Android imageloader异步方式显示图片的 Android imageloader异步方式显示图片的怎么样在图片读取完成之后返回,需要怎么写ImageLoadingListener 解决方案 Universal-Image-Loader 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等 支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置 支持图片的内存缓存,

Asp.net中C#使用Socket发送和接收TCP数据示例

程序代码  代码如下 复制代码 using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; namespace ConsoleApplication1 {     public static class SocketTest     {         private static Encoding encode = Encoding.

UDP 接收数据同步 异步选择问题

问题描述 同步加线程使用事件并发处理接收到的数据publicvoidSyncRecive(){Tasklisten=newTask(()=>{while(true){intlength=connect.ReceiveFrom(this.packetBuffer,0,this.packetBuffer.Length,SocketFlags.None,refthis.remoteEndPoint);byte[]packet=this.packetBuffer.Unpack(length);if(le

线程池-以http get方式发送大量数据

问题描述 以http get方式发送大量数据 项目需求,需要将大量实时数据从kafka拉下,并发送到第三方给定的url地址,并且第三方规定,只能用短连接. 目前是采用一个线程池共享一个httpclient实例来批量发送,但是总觉得这种短连接发挥不了httpclient的功能,并且在使用中还有大量的连接超时.读超时等异常,甚至比使用原生的java URLconnection的异常还要多. 虽说httpclient自带重发功能,但是时间一长,还发现程序有卡死的现象,通过jstack发现,死锁的出现正

TCP 异步传输数据 接收端数据包混乱

问题描述 用TCP异步接收数据,接收到的数据包出现数据重叠的情况,请问这是为什么?举例:发送:10121314151617181911121314151617181901接收:101213141516171415161718191112131121314151617181901实际通信的数据包大概有2k-3k,上面的例子只是想说明一下情况.请各位大神帮忙解决一下! 解决方案 解决方案二:确定包头包尾呢??解决方案三:引用1楼SomethingJack的回复: 确定包头包尾呢?? 确定了包头包尾了

解决网络不通数据只发送不接收

网络的畅通是表现在既有发送包,也有接收包,只有来去都畅通才正常.但是如果只有发送,却没有接收,碰到这样的故障到底又是怎么回事呢?在笔者短暂的两年网管生涯中,出现了几次这样的故障,但他们发生的原因又各有不同.今天笔者就把一些解决方法奉献给大家. 一般来说,出现这种故障的时候,网络连接都是都是好的,即不会出现红色的叉子图标.但这又只是一种表现的正常,因此我们入手的时候必须先从自身入手. 从自身入手的第一点就是检查出现该故障前有没有安装过什么软件,有没有改过什么设置,尤其是杀毒软件.防火墙这一类的软件

python通过get,post方式发送http请求和接收http响应的方法

  本文实例讲述了python通过get,post方式发送http请求和接收http响应的方法.分享给大家供大家参考.具体如下: 测试用CGI,名字为test.py,放在apache的cgi-bin目录下: ? 1 2 3 4 5 6 7 8 9 10 #!/usr/bin/python import cgi def main(): print "Content-type: text/htmln" form = cgi.FieldStorage() if form.has_key(&q

AS3中数据发送与接收

先回顾一下as2中相关的解决办法 相信大部分人用的都是LoadVars类吧   1 var xianshi_lv = new LoadVars(); 2 xianshi_lv.bianliang1 = "变量一"; 3 xianshi_lv.bianliang2 = "变量二"; 4 xianshi_lv.bianliang3 = "变量三"; 5 xianshi_lv.sendAndLoad("http://10.7.87.222/s

nat穿透 udp-谁给一个在两个不同局域网内的主机,实现socket编程,能够发送和接收简单的数据

问题描述 谁给一个在两个不同局域网内的主机,实现socket编程,能够发送和接收简单的数据 本鸟在 网上查了一下资料,大部分都是关于tcp,udp穿透nat的方案,有一种是通过在一个外网的服务端的基础上实现,这得需要买一个外网ip,这种方案,我放弃了,我没钱买一个在公网上的ip 还一种一方端口映射,,不用外网的ip这种方式怎么实现啊??难道只是在路由器的转发规则,虚拟服务器上把自己的主机的ip和那个端口号添上就可以吗??上就可以吗??