在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
It hasn't been thoroughly tested, but seems to work OK. using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; namespace Server { public class Server { private int port; private Socket serversocket; public delegate void ConnectionEvent(Connection conn); public List<Connection> connections; public event ConnectionEvent AcceptCallback; public event ConnectionEvent RecieveCallback; public event ConnectionEvent DisconnectCallback; public Server(int p) { port = p; connections = new List<Connection>(500); } public bool Start() { IPEndPoint ipendpoint; try { //do not assign an IP, as it is a server (IPAdress.Any) ipendpoint = new IPEndPoint(IPAddress.Any, this.port); } catch (ArgumentOutOfRangeException e) { //port was probably out of range throw new ArgumentOutOfRangeException("Please check port number.", e); } try { //create the main server worker socket serversocket = new Socket(ipendpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } catch (SocketException e) { //here because we couldn't create server socket throw new ApplicationException("Couldn't create server socket.", e); } try { //bind the socket to the specified port serversocket.Bind(ipendpoint); //begin listening for incoming connections serversocket.Listen(100); } catch (SocketException e) { //probably here due to the port being in use throw new ApplicationException("Couldn't bind/listen on port: " + this.port.ToString(), e); } try { //begin accepting incoming connections serversocket.BeginAccept(new AsyncCallback(acceptCallback), this.serversocket); } catch (Exception e) { throw new ApplicationException("Error assigning the accept callback.", e); } return true; } private void acceptCallback(IAsyncResult ar) { Connection conn = new Connection(); try { //finish the connection //get the resulting state object Socket sck = (Socket)ar.AsyncState; //create new connection object to be added to our concurrent connection list conn = new Connection(sck.EndAccept(ar)); //lock our list for thread safety lock(connections) { //add to our list connections.Add(conn); } //begin accepting data on that socket, using our Connection object as the object state conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), conn); //start accepting connections again serversocket.BeginAccept(new AsyncCallback(acceptCallback), this.serversocket); //if the eventhandler for incoming connections has been assgined, call it if(AcceptCallback != null) { AcceptCallback(conn); } } catch(SocketException e) { Disconnect(conn); throw new ApplicationException(e.Message, e); } } private void Disconnect(Connection conn) { //remove connection from list lock (connections) { connections.Remove(conn); } //make sure it's completely closed conn.socket.Close(); //if the eventhandler for disconnection has been assgined, call it if (DisconnectCallback != null) { DisconnectCallback(conn); } } private void receiveCallback(IAsyncResult ar) { //retrieve the connection that has data ready Connection conn = (Connection)ar.AsyncState; try { //retrieve the data(bytes) while also returning how many bytes were read int bytes = conn.socket.EndReceive(ar); //if bytes is more than zero, then data was successfully read if(bytes > 0) { //if the data receive callback has been assigned, call it if(RecieveCallback != null) { RecieveCallback(conn); } //being receiving data again conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), conn); } else { //if zero bytes were read, connection was closed Disconnect(conn); } } catch(SocketException e) { Disconnect(conn); throw new ApplicationException("Error with EndReceive or BeginReceive", e); } } } } Connection.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; namespace Server { public class Connection { public byte[] buffer; public Socket socket; public Connection() { } public Connection(Socket sock) { buffer = new byte[1024]; socket = sock; } public void Send(string data) { try { if (this.socket.Connected) { //convert string into an aray of bytes byte[] buffer = ASCIIEncoding.ASCII.GetBytes(data); //send our byte[] buffer socket.Send(buffer, SocketFlags.None); } } catch (SocketException e) { throw new ApplicationException("Error with Send", e); } } } } Usage:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace Server { class Program { static void Main(string[] args) { //port 80(webserver) Server server = new Server( 80 ); server.RecieveCallback += server_RecieveCallback; server.AcceptCallback += server_AcceptCallback; server.DisconnectCallback += server_DisconnectCallback; server.Start(); ThreadStart threadstart = new ThreadStart(ThreadJob); Thread thread = new Thread(threadstart); thread.Start(); } static void server_DisconnectCallback(Connection conn) { Console.WriteLine("Connection disconnected\n"); } static void server_AcceptCallback(Connection conn) { Console.WriteLine("Incoming connection\n"); } static void ThreadJob() { while (true) Thread.Sleep(1); } static void server_RecieveCallback(Connection conn) { Console.WriteLine(ASCIIEncoding.ASCII.GetString(conn.buffer)); } } } Go to your web browser and type 127.0.0.1 into the address bar.
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论