转载:Socket 服务器端与客户端例子(异步模式)

来源:互联网 发布:云数据库 免费 编辑:程序博客网 时间:2024/04/30 00:39

服务器端

=====================================

using System;
using System.Collections;
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 SocketServer
{
    public partial class Form1 : Form
    {
        private IPAddress serverip = IPAddress.Parse("127.0.0.1");//以本机作测试
        int port = 8000;
        private IPEndPoint serverfulladdr;//完整终端地址
        private Socket sock;
        private System.Timers .Timer  mytimer;

        private ArrayList alsock;//当建立了多个连接时用于保存连接

 

        public Form1()
        {
           
            InitializeComponent();
            Start();
            
        }
        void Start()
        {
            try
            {
                serverfulladdr = new IPEndPoint(serverip, port);//取端口号1000

                //构造socket对象,套接字类型为“流套接字”,指定五元组中的协议元

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

                //指定五元组中的本地二元,即本地主机地址和端口号
                sock.Bind(serverfulladdr);
                //监听是否有连接传入,指定挂起的连接队列的最大值为20
                sock.Listen(20);
                alsock = new ArrayList();

                //构造定时器,时间间隙为1秒,即每隔一秒执行一次accept()方法,以获取连接请求队列中//第一个挂起的连接请求

                mytimer = new System.Timers.Timer(1000);

                mytimer.Elapsed += new System.Timers.ElapsedEventHandler(mytimer_elapsed);

                mytimer.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message );
            }
        }
        private void btstart_click(object sender, EventArgs e)
        {

            Start();

        }


        private void mytimer_elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

            mytimer.Enabled = false;

            //执行accept(),当挂起队列为空时将阻塞本线程,同时由于上一语句,定时器将停止,直//至有连接传入

            Socket acceptsock = sock.Accept();

            //将accept()产生的socket对象存入arraylist

            alsock.Add(acceptsock);

            // 构造threading.timer对象,这将导致程序另启线程。线程将执行回调函数,该委托限制//函数参数须为object型。threading.timer构造器的第二个参数即传入回调函数的参数;第//三个参数指定调用回调函数之前的延时,取0则立即启动;最后一个参数指定调用回调函数//的时间间隔,取0则只执行一次。

            System.Threading.Timer ti = new System.Threading.Timer(new TimerCallback(receivemsg), acceptsock, 0, 0);

            mytimer.Enabled = true;

        }

         private void receivemsg(object obj)
        {

           Socket acceptsock = (Socket)obj;

            try

            {

                while (true)

                {

                    byte[] bytearray = new byte[100];

                    acceptsock.Receive(bytearray);//接收数据

                    //将字节数组转成字符串

                    string strrec = System.Text.Encoding.UTF8.GetString(bytearray);

                    if (this.rtbreceive.InvokeRequired)

                    {

                        this.rtbreceive.Invoke(new EventHandler(changericktextbox), new object[] { strrec, EventArgs.Empty });

                    }

                }

            }

            catch(Exception ex)

            {

                acceptsock.Close();

                MessageBox.Show("s:receive message error"+ex.Message );

            }

        }

 

        private void changericktextbox(object obj,EventArgs e)

        {

            string s = System.Convert.ToString(obj);

            this.rtbreceive.AppendText(s + Environment.NewLine );

        }

 

        private void btsend_click(object sender, EventArgs e)

        {

            Socket sc=null;

            byte[] bytesend = System.Text.Encoding.UTF8 .GetBytes(this.tbsend.Text.ToCharArray());

            try

            {

                //同时存在若干个客户端连接时,在textbox1中输入要发送的是哪个连接

                int index = int.Parse(this.textbox1.Text.Trim());

                sc = (Socket)alsock[index - 1];

                //发送数据

                sc.Send(bytesend);

            }

            catch(Exception ex)

            {

                if(sc != null)

                {

                                sc.Close();

                }

                MessageBox.Show("s:send message error"+ex.Message );

            }

        }

 

        private void btclose_click(object sender, EventArgs e)
        {

            try

            {

                Application.Exit();

            }

            catch (Exception ex)

            {

                MessageBox.Show("s:close socket error" + ex.Message );

            }

        }

    }

}


 ========================================

客户端

 

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 SocketApp
{
    public partial class FormMain : Form
    {
        Socket connectSocket;
        //Socket client;
        byte[] bytes = new byte[1024];
        delegate void listboxDel(string s);
        listboxDel listboxdel;


        delegate void richTextBoxDel(string s);
        richTextBoxDel richtextboxdel;

        string IP = "127.0.0.1";//"192.168.1.168";
        int port = 10000;
        public FormMain()
        {
            InitializeComponent();

            textBoxContent.Focus();
            listboxdel = new listboxDel(listbox);
            richtextboxdel = new richTextBoxDel(richtextbox);

            //为连接指派线程
            Thread threadConnect = new Thread(new ThreadStart(Connect));
            threadConnect.Start();
        }
        #region 异步访问控件代理
        public void listbox(string str)
        {
            listBox1.Items.Add(str);
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            listBox1.ClearSelected();

           // richTextBox1.Text = richTextBox1.Text +"\r" +str;
        }
        /// <summary>
        /// 代理
        /// </summary>
        /// <param name="str"></param>
        public void richtextbox(string str)
        {
            richTextBox1.Text = str;

        }
        #endregion
       
        #region 与服务器连接
        //连接方法
        public void Connect()
        {
            try
            {
                //建立连接socket
                connectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //开始异步连接
                connectSocket.BeginConnect(IPAddress.Parse(IP),
                                    port,
                                    new AsyncCallback(ConnectCallback),  //定义回调函数代理
                                    connectSocket);                      //传递给回调函数的状态
            }
            catch (Exception e)
            {
                //MessageBox.Show(e.Message);
                this.richTextBox1.Invoke(richtextboxdel, "Connect:" + e.ToString());
             
            }
        }
        //连接方法的回调函数
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                //从传递的状态中获取套接字,创建一个客户端套接字
                Socket client = (Socket)ar.AsyncState;
                //完成挂起的连接操作
                client.EndConnect(ar);
                listBox1.Invoke(listboxdel, "连接服务器成功,可以开始通话!");
                client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
            }
            catch (Exception e)
            {

                this.richTextBox1.Invoke(richtextboxdel, "ConnectCallback:" + e.ToString());
                //Console.WriteLine(e.ToString());
               
            }
        }
        #endregion

        #region 发送数据之后保持接受数据

        public void receivecallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                int length = client.EndReceive(ar);
                string str =  Encoding.UTF8.GetString(bytes, 0, length);
                if (!string.IsNullOrEmpty(str))
                {
                    listBox1.Invoke(listboxdel, str);
                }
                //继续访问服务器,及时 接受他人发送的数据
                client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
            }
            catch (Exception e)
            {
                this.richTextBox1.Invoke(richtextboxdel, "receivecallback:" + e.ToString());
              
            }
        }
        #endregion


        private void button1_Click(object sender, EventArgs e)
        {
            //Send(textBoxUser.Text + ":" + textBoxContent.Text);
            string ss = textBoxUser.Text + ":" + textBoxContent.Text;
            Send(ss);

        }

        #region 发送数据
        //发送方法
        private void Send(String data)
        {
            //使用ASCII转换字符串为字节序列
            byte[] byteData = Encoding.UTF8.GetBytes(data);   //将字符串转换成字节序列
            //开始向远端设备发送数据
            connectSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,  new AsyncCallback(SendCallback), connectSocket);
        }
        //发送方法的回调函数 //本季记录发送内容
        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                //从传递的状态中获取套接字,创建一个客户端套接字
                Socket client = (Socket)ar.AsyncState;
                //结束异步数据传输操作,返回传输的字节数
                int bytesSent = client.EndSend(ar);
                string ss = textBoxUser.Text + ":" + textBoxContent.Text;

                listBox1.Invoke(listboxdel, ss);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
        #endregion

    }
}

 

原创粉丝点击