C#下用select方法实现socket服务端

select是一种比较古老但一直被证明性能很好的socket模式,它可以让你以消息驱动的模式书写socket程序。网上C++的例子很多,但C#的例子极少。

上代码:

namespace Server
{
    class Program
    {
        // Thread signal.
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    private static Socket handler = null;
    private static ArrayList g_CliSocketArr = new ArrayList();
    private static Object thisLock = new Object();
    public Program()
    {
    }

    public static void StartListening() {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        IPAddress ipAddress = IPAddress.Parse("192.168.1.71");//
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp );

        // Bind the socket to the local endpoint and listen for incoming connections.
        try {
            listener.Bind(localEndPoint);
            listener.Listen(100);

            // Start an asynchronous socket to listen for connections.
            Console.WriteLine("Waiting for a connection...");

            Thread worker = new Thread(new ThreadStart(WorkerThread));//创建一个线程用于处理请求
            worker.Start();
            while (true)
            {
                Socket sClient = listener.Accept();
                Console.WriteLine("There is a new connection.");
                g_CliSocketArr.Add(sClient);

            }

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }
        public static void WorkerThread()
        {
            Socket socket1 = null;
            ArrayList readList = new ArrayList();
      //      readList.Add(socket0);
            while (true)
            {
                lock (thisLock)
                {
                    readList.Clear();
                    for (int i = 0; i < g_CliSocketArr.Count; i++)
                    {
                        readList.Add(g_CliSocketArr[i]);
                    }
                }
                if (readList.Count <= 0)
                {
                    Thread.Sleep(100);
                    continue;
                }
                try
                {
                    Socket.Select(readList, null, null, 500);
                    for (int i = 0; i < readList.Count; i++)
                    {
                        socket1 = (Socket)readList[i];
                        Console.WriteLine("There is a new message from client.");
                        byte[] buffer = new byte[1024];

                            int recLen = socket1.Receive(buffer);
                            if(recLen > 0)
                            {
                            //    recLen = socket1.Receive(buffer);
                            }
                            else
                            {//如果返回0,表示客户端已经断开连接,须将此socket关闭然后从连接池中清除
                                Console.WriteLine("Rece 0 length.");
                                for (int ii = 0; ii < g_CliSocketArr.Count; ii++)
                                {
                                    Socket s = (Socket)g_CliSocketArr[ii];
                                    if (s == socket1)
                                        g_CliSocketArr.RemoveAt(ii);
                                }
                                socket1.Shutdown(SocketShutdown.Both);
                                socket1.Close();
                                break;
                            }
                            socket1.Send(buffer,recLen, SocketFlags.None);

                    }
                }
                catch (SocketException e)
                {
                    Console.WriteLine("{0} Error code: {1}.", e.Message, e.ErrorCode);

                    for (int ii = 0; ii < g_CliSocketArr.Count; ii++)
                    {
                        Socket s = (Socket)g_CliSocketArr[ii];
                        if (s == socket1)
                            g_CliSocketArr.RemoveAt(ii);
                    }
                    socket1.Shutdown(SocketShutdown.Both);
                    socket1.Close();
                }
            }

        }

        static void Main(string[] args)
        {
            StartListening();
        }

    }

}

C#下用select方法实现socket服务端

时间: 2024-08-10 23:26:30

C#下用select方法实现socket服务端的相关文章

Socket服务端一直收空包的原因与解决方法

最近做socket服务端,大部分时候系统是正常的,但是运行个一段时间就会一直以超高的频率收到很多数据,一开始以为是下位机上报的,没怎么上心,后来下位机工程师说他们没上报,所以重新看了下代码,发现程序会一直调用 netStream.BeginRead,EndRead,一直收数据,而且受到的数据包都是0字节,百度了20分钟,大神们说socket客户端正常关闭的时候服务端会收到一个长度是0的数据包,如果一直循环调用会一直收到,原话如下 出现原因:一.用户正常退出,这时你还循环调用了Receive方法时

C# Socket服务端与客户端通信(包含大文件的断点传输)

步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收信息   (3)发送数据(这里分发送字符串.文件(包含大文件).震动) 二.客户端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收信息   (3)发送数据(这里分发送

Linux下更改oracle客户端字符集和服务端字符集

from:http://blog.csdn.net/chid/article/details/6166506 Linux 下更改 oracle 客户端字符集和服务端字符集 1.Linux 下更改 oracle 客户端字符集,即设置环境变量" NLS_LANG" 的值 查看客户端字符集,在终端下执行: echo $NLS_LANG 修改客户端字符集: sudo gedit /etc/environment 在environment 文件中增加以下内容: NLS_LANG="SI

socket服务端和客户端

#!/usr/bin/env python#encoding: utf-8import socketdef handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") client.send("Hello, World") def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREA

使用NewLife网络库构建可靠的自动售货机Socket服务端(一)

最近有个基于tcp socket 协议和设备交互需求,想到了新生命团队的各种组件,所以决定用NewLife网络库作为服务端来完成一系列的信息交互. 第一,首先说一下我们需要实现的功能需求吧 1,首先客户有一堆自动售货机的设备,设备连接socket服务端后 定时发送设备实时状态作为心跳信息,并且服务端需要下发信息予以确认. 2,需要知道设备的实时在线状态 3,设备需要实现微信,支付宝扫码支付需求,当客户买东西的时候选择扫码支付时,设备上报产品价格信息,支付方式,服务器下发微信或者支付宝的当面付二维

最简单的一个socket服务端

描述:这是一个socket服务端,可以用串口调试工具连接和发送数据过来 package com.thinkgem.wlw.modules.lhjh.socket.tstandard; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import j

C# Socket服务端和客户端互相send和receive

服务端 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Net.Sockets; 5 using System.Net; 6 using System.Threading; 7  8 namespace Controller 9 {10     public static class SocketServer11     {12         private stat

Java网络编程【Socket服务端和客户端】

Socket 编程大家都不陌生,Java 学习中必学的部分,也是 Java网络编程核心内容之一.Java 网络编程又包括 TCP.UDP,URL 等模块.TCP 对应 Socket模块,UDP 对应 DatagramPacket 模块.URL 对应 URL 模块.其中 TCP 和 UDP 是网络传输协议,TCP 是数据流传输协议,UDP 是数据包传输协议.两者之间的异同就不在这里说了,推荐一本入门书籍 <TCPIP入门经典>.我们开始 Socket 服务端和客户端编程吧. 一.Socket 服

socket服务端处理多个客户端的请求学习理解

socket服务端处理多个客户端的请求:while(true){Socket s=ss.accept();new WorkThread(s).start();}class WorkThread edtends Thread{private Socket s;public WorkThread(Socket s){this.s=s;}public void run(){s.getInput();s.getOutput();}}