⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockets.cs

📁 Manager the door by fingerprint machine
💻 CS
📖 第 1 页 / 共 2 页
字号:
// Client-server helpers for TCP/IP
// ClientInfo: wrapper for a socket which throws
//  Receive events, and allows for messaged communication (using
//  a specified character as end-of-message)
// Server: simple TCP server that throws Connect events
// ByteBuilder: utility class to manage byte arrays built up
//  in multiple transactions

// (C) Richard Smith 2005-7
//   bobjanova@gmail.com
// You can use this for free and give it to people as much as you like
// as long as you leave a credit to me :).

// Code to connect to a SOCKS proxy modified from
//   http://www.thecodeproject.com/csharp/ZaSocks5Proxy.asp

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Collections;
using System.Net.Sockets;


namespace RedCorona.Net {
	public delegate void ConnectionRead(ClientInfo ci, String text);
	public delegate void ConnectionClosed(ClientInfo ci);
	public delegate void ConnectionReadBytes(ClientInfo ci, byte[] bytes, int len);
	public delegate void ConnectionReadMessage(ClientInfo ci, uint code, byte[] bytes, int len);
	
	public enum ClientDirection {In, Out, Left, Right, Both};
	public enum MessageType {Unmessaged, EndMarker, Length, CodeAndLength};
	
	// OnReadBytes: catch the raw bytes as they arrive
	// OnRead: for text ended with a marker character
	// OnReadMessage: for binary info on a messaged client
	public class ClientInfo {
		internal Server server = null;
		private Socket sock;
		private String buffer;
		public ConnectionRead OnRead;
		public ConnectionClosed OnClose;
		public ConnectionReadBytes OnReadBytes;
		public ConnectionReadMessage OnReadMessage;
		public MessageType MessageType;
		private ClientDirection dir;
		int id;
		bool alreadyclosed = false;
		public static int NextID = 100;
		//private ClientThread t;
		public object Data = null;
		
		private char delim;
		public const int BUFSIZE = 1024;
		byte[] buf = new byte[BUFSIZE];
		ByteBuilder bytes = new ByteBuilder(10);
		
		byte[] msgheader = new byte[8];
		byte headerread = 0;
		
		public char Delimiter {
			get { return delim; }
			set { delim = value; }
		}
		
		public ClientDirection Direction { get { return dir; } }
		public Socket Socket { get { return sock; } }
		public Server Server { get { return server; } }
		public int ID { get { return id; } }
		
		public bool Closed {
			get { return !sock.Connected; } 
		}
		
		public ClientInfo(Socket cl, bool StartNow) : this(cl, null, null, ClientDirection.Both, StartNow) {}
		public ClientInfo(Socket cl, ConnectionRead read, ConnectionReadBytes readevt, ClientDirection d) : this(cl, read, readevt, d, true) {}
		public ClientInfo(Socket cl, ConnectionRead read, ConnectionReadBytes readevt, ClientDirection d, bool StartNow){	
			sock = cl; buffer = ""; OnReadBytes = readevt;
			OnRead = read;
			MessageType = MessageType.EndMarker;
			dir = d; delim = '\n';
			id = NextID; // Assign each client an application-unique ID
			unchecked{NextID++;}
			//t = new ClientThread(this);
			if(StartNow) BeginReceive();
		}
		
		public void BeginReceive(){
//			t.t.Start();
			sock.BeginReceive(buf, 0, BUFSIZE, 0, new AsyncCallback(ReadCallback), this);
		}
		
		public String Send(String text){
			byte[] ba = Encoding.UTF8.GetBytes(text);
			String s = "";
			for(int i = 0; i < ba.Length; i++) s += ba[i] + " ";
			sock.Send(ba);
			return s;
		}
		
		public void SendMessage(uint code, byte[] bytes){ SendMessage(code, bytes, 0, bytes.Length); }
		public void SendMessage(uint code, byte[] bytes, byte paramType){ SendMessage(code, bytes, paramType, bytes.Length); }
		public void SendMessage(uint code, byte[] bytes, byte paramType, int len){
			if(paramType > 0){
				ByteBuilder b = new ByteBuilder(3);
				b.AddParameter(bytes, paramType);
				bytes = b.Read(0, b.Length);
				len = bytes.Length;
			} 
			
			lock(sock){
				switch(MessageType){
					case MessageType.CodeAndLength:
						sock.Send(UintToBytes(code));
						sock.Send(IntToBytes(len));
						break;
					case MessageType.Length:
						sock.Send(IntToBytes(len));
						break;
				}
				sock.Send(bytes, len, SocketFlags.None);
			}
		}
		
		public bool MessageWaiting(){
			FillBuffer(sock);
			return buffer.IndexOf(delim) >= 0;
		}
		
		public String Read(){
			//FillBuffer(sock);
			int p = buffer.IndexOf(delim);
			if(p >= 0){
				String res = buffer.Substring(0, p);
				buffer = buffer.Substring(p + 1);
				return res;
			} else return "";
		}
		
		private void FillBuffer(Socket sock){
			byte[] buf = new byte[256];
			int read;
			while(sock.Available != 0){
				read = sock.Receive(buf);
				if(OnReadBytes != null) OnReadBytes(this, buf, read);
				buffer += Encoding.UTF8.GetString(buf, 0, read);
			}
		}
		
		void ReadCallback(IAsyncResult ar){
			try {
				int read = sock.EndReceive(ar);
				//Console.WriteLine("Socket "+ID+" read "+read+" bytes");
				if(read > 0){
					DoRead(buf, read);
					BeginReceive();
				} else {
					Close();
				}
			} catch(SocketException){ Close();	} catch(ObjectDisposedException){	Close();	}
		}
		
		internal void DoRead(byte[] buf, int read){
			if(read > 0){
				if(OnReadBytes != null) OnReadBytes(this, buf, read);
				if(OnRead != null){ // Simple text mode
					buffer += Encoding.UTF8.GetString(buf, 0, read);
					while(buffer.IndexOf(delim) >= 0) OnRead(this, Read());
				}
			}
			ReadInternal(buf, read);
		}
		
		void ReadInternal(byte[] buf, int read){
			if((OnReadMessage != null) && (MessageType != MessageType.Unmessaged)){
				// Messaged mode
				int copied;
				uint code = 0;
				switch(MessageType){
					case MessageType.CodeAndLength:
					case MessageType.Length:
						int length;
						if(MessageType == MessageType.Length){
							copied = FillHeader(ref buf, 4, read);						
							if(headerread < 4) break;
							length = GetInt(msgheader, 0, 4);
						} else{
							copied = FillHeader(ref buf, 8, read);
							if(headerread < 8) break;
							code = (uint)GetInt(msgheader, 0, 4);
							length = GetInt(msgheader, 4, 4);
						}
						bytes.Add(buf, 0, read - copied);
						if(bytes.Length >= length){
							// A message was received!
						 headerread = 0;
							byte[] msg = bytes.Read(0, length);
							OnReadMessage(this, code, msg, length);
							// Don't forget to put the rest through the mill
							byte[] whatsleft = bytes.Read(length, bytes.Length - length);
							bytes.Clear();
							if(whatsleft.Length > 0) ReadInternal(whatsleft, whatsleft.Length);
						}
						//if(OnStatus != null) OnStatus(this, bytes.Length, length);
						break;
				}
			}
		}
		
		int FillHeader(ref byte[] buf, int to, int read) {
			int copied = 0;
			if(headerread < to){
				// First copy the header into the header variable.
				for(int i = 0; (i < read) && (headerread < to); i++, headerread++, copied++){
					msgheader[headerread] = buf[i];
				}
			}
			if(copied > 0){
				// Take the header bytes off the 'message' section
				byte[] newbuf = new byte[read - copied];
				for(int i = 0; i < newbuf.Length; i++) newbuf[i] = buf[i + copied];
				buf = newbuf;
			}
			return copied;
		}
		
		public static int GetInt(byte[] ba, int from, int len){
			int r = 0;
			for(int i = 0; i < len; i++)
				r += ba[from + i] << ((len - i - 1) * 8);
			return r;
		}
		
		public static int[] GetIntArray(byte[] ba){
			int[] res = new int[ba.Length / 4];
			for(int i = 0; i < res.Length; i++){
				res[i] = GetInt(ba, i * 4, 4);
			}
			return res;
		}
		
		public static uint[] GetUintArray(byte[] ba){
			uint[] res = new uint[ba.Length / 4];
			for(int i = 0; i < res.Length; i++){
				res[i] = (uint)GetInt(ba, i * 4, 4);
			}
			return res;
		}
		
		public static byte[] IntToBytes(int val){ return UintToBytes((uint)val); }
		public static byte[] UintToBytes(uint val){
			byte[] res = new byte[4];
			for(int i = 3; i >= 0; i--){
				res[i] = (byte)val; val >>= 8;
			}
			return res;
		}
		
		public static byte[] IntArrayToBytes(int[] val){
			byte[] res = new byte[val.Length * 4];
			for(int i = 0; i < val.Length; i++){
				byte[] vb = IntToBytes(val[i]);
				res[(i * 4)] = vb[0];
				res[(i * 4) + 1] = vb[1];
				res[(i * 4) + 2] = vb[2];
				res[(i * 4) + 3] = vb[3];
			}
			return res;
		}
		
		public static byte[] UintArrayToBytes(uint[] val){
			byte[] res = new byte[val.Length * 4];
			for(uint i = 0; i < val.Length; i++){
				byte[] vb = IntToBytes((int)val[i]);
				res[(i * 4)] = vb[0];
				res[(i * 4) + 1] = vb[1];
				res[(i * 4) + 2] = vb[2];
				res[(i * 4) + 3] = vb[3];
			}
			return res;
		}
		
		public void Close(){
			if(!alreadyclosed){
				if(server != null) server.ClientClosed(this);
				if(OnClose != null) OnClose(this);
				alreadyclosed = true;
			}
			sock.Close();
		}
	}
	
	public class Sockets {
		// Socks proxy inspired by http://www.thecodeproject.com/csharp/ZaSocks5Proxy.asp
		public static SocksProxy SocksProxy;
		public static bool UseSocks = false;
		
		public static Socket CreateTCPSocket(String address, int port){return CreateTCPSocket(address, port, UseSocks, SocksProxy);}
		public static Socket CreateTCPSocket(String address, int port, bool useSocks, SocksProxy proxy){
			Socket sock;
			if(useSocks) sock = ConnectToSocksProxy(proxy.host, proxy.port, address, port, proxy.username, proxy.password);
			else {
				IPAddress host = Dns.GetHostByName(address).AddressList[0];
				sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
				sock.Connect(new IPEndPoint(host, port));
			}
			return sock;
		}

		private static string[] errorMsgs=	{
			"Operation completed successfully.",
			"General SOCKS server failure.",
			"Connection not allowed by ruleset.",
			"Network unreachable.",
			"Host unreachable.",
			"Connection refused.",
			"TTL expired.",
			"Command not supported.",
			"Address type not supported.",
			"Unknown error."
		};

		public static Socket ConnectToSocksProxy(IPAddress proxyIP, int proxyPort, String destAddress, int destPort, string userName, string password){
			byte[] request = new byte[257];
			byte[] response = new byte[257];
			ushort nIndex;
			
			IPAddress destIP = null;
			
			try{ destIP = IPAddress.Parse(destAddress); }
			catch { }
			
			IPEndPoint proxyEndPoint = new IPEndPoint(proxyIP, proxyPort);

			// open a TCP connection to SOCKS server...
			Socket s;
			s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
			s.Connect(proxyEndPoint);	
/*			} catch(SocketException){
				throw new SocketException(0, "Could not connect to proxy server.");
			}*/

			nIndex = 0;
			request[nIndex++]=0x05; // Version 5.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -