📄 sockets.cs
字号:
request[nIndex++]=0x02; // 2 Authentication methods are in packet...
request[nIndex++]=0x00; // NO AUTHENTICATION REQUIRED
request[nIndex++]=0x02; // USERNAME/PASSWORD
// Send the authentication negotiation request...
s.Send(request,nIndex,SocketFlags.None);
// Receive 2 byte response...
int nGot = s.Receive(response,2,SocketFlags.None);
if (nGot!=2)
throw new ConnectionException("Bad response received from proxy server.");
if (response[1]==0xFF)
{ // No authentication method was accepted close the socket.
s.Close();
throw new ConnectionException("None of the authentication method was accepted by proxy server.");
}
byte[] rawBytes;
if (/*response[1]==0x02*/true)
{//Username/Password Authentication protocol
nIndex = 0;
request[nIndex++]=0x05; // Version 5.
// add user name
request[nIndex++]=(byte)userName.Length;
rawBytes = Encoding.Default.GetBytes(userName);
rawBytes.CopyTo(request,nIndex);
nIndex+=(ushort)rawBytes.Length;
// add password
request[nIndex++]=(byte)password.Length;
rawBytes = Encoding.Default.GetBytes(password);
rawBytes.CopyTo(request,nIndex);
nIndex+=(ushort)rawBytes.Length;
// Send the Username/Password request
s.Send(request,nIndex,SocketFlags.None);
// Receive 2 byte response...
nGot = s.Receive(response,2,SocketFlags.None);
if (nGot!=2)
throw new ConnectionException("Bad response received from proxy server.");
if (response[1] != 0x00)
throw new ConnectionException("Bad Usernaem/Password.");
}
// This version only supports connect command.
// UDP and Bind are not supported.
// Send connect request now...
nIndex = 0;
request[nIndex++]=0x05; // version 5.
request[nIndex++]=0x01; // command = connect.
request[nIndex++]=0x00; // Reserve = must be 0x00
if (destIP != null)
{// Destination adress in an IP.
switch(destIP.AddressFamily)
{
case AddressFamily.InterNetwork:
// Address is IPV4 format
request[nIndex++]=0x01;
rawBytes = destIP.GetAddressBytes();
rawBytes.CopyTo(request,nIndex);
nIndex+=(ushort)rawBytes.Length;
break;
case AddressFamily.InterNetworkV6:
// Address is IPV6 format
request[nIndex++]=0x04;
rawBytes = destIP.GetAddressBytes();
rawBytes.CopyTo(request,nIndex);
nIndex+=(ushort)rawBytes.Length;
break;
}
}
else
{// Dest. address is domain name.
request[nIndex++]=0x03; // Address is full-qualified domain name.
request[nIndex++]=Convert.ToByte(destAddress.Length); // length of address.
rawBytes = Encoding.Default.GetBytes(destAddress);
rawBytes.CopyTo(request,nIndex);
nIndex+=(ushort)rawBytes.Length;
}
// using big-edian byte order
byte[] portBytes = BitConverter.GetBytes((ushort)destPort);
for (int i=portBytes.Length-1;i>=0;i--)
request[nIndex++]=portBytes[i];
// send connect request.
s.Send(request,nIndex,SocketFlags.None);
s.Receive(response); // Get variable length response...
if (response[1]!=0x00)
throw new ConnectionException(errorMsgs[response[1]]);
// Success Connected...
return s;
}
}
public struct SocksProxy {
public IPAddress host;
public ushort port;
public string username, password;
public SocksProxy(String hostname, ushort port, String username, String password){
this.port = port;
host = Dns.GetHostByName(hostname).AddressList[0];
this.username = username; this.password = password;
}
}
public class ConnectionException: Exception {
public ConnectionException(string message) : base(message) {}
}
// Server code cribbed from Framework Help
public delegate bool ClientConnect(Server serv, ClientInfo new_client); // whether to accept the client
public class Server {
class ClientState {
// To hold the state information about a client between transactions
internal Socket Socket = null;
internal const int BufferSize = 1024;
internal byte[] buffer = new byte[BufferSize];
internal StringBuilder sofar = new StringBuilder();
internal ClientState(Socket sock){
Socket = sock;
}
}
ArrayList clients = new ArrayList();
Socket ss;
public ClientConnect Connect;
public IEnumerable Clients {
get { return clients; }
}
public Socket ServerSocket {
get { return ss; }
}
public ClientInfo this[int id]{
get {
foreach(ClientInfo ci in Clients)
if(ci.ID == id) return ci;
return null;
}
}
public int Port {
get { return ((IPEndPoint)ss.LocalEndPoint).Port; }
}
public Server(int port) : this(port, null) {}
public Server(int port, ClientConnect connDel) {
Connect = connDel;
ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
ss.Bind(new IPEndPoint(IPAddress.Any, port));
ss.Listen(100);
// Start the accept process. When a connection is accepted, the callback
// must do this again to accept another connection
ss.BeginAccept(new AsyncCallback(AcceptCallback), ss);
}
internal void ClientClosed(ClientInfo ci){
clients.Remove(ci);
}
public void Broadcast(byte[] bytes){
foreach(ClientInfo ci in clients) ci.Socket.Send(bytes);
}
public void BroadcastMessage(uint code, byte[] bytes){BroadcastMessage(code, bytes, 0); }
public void BroadcastMessage(uint code, byte[] bytes, byte paramType){
foreach(ClientInfo ci in clients) ci.SendMessage(code, bytes, paramType);
}
// ASYNC CALLBACK CODE
void AcceptCallback(IAsyncResult ar) {
try{
Socket server = (Socket) ar.AsyncState;
Socket cs = server.EndAccept(ar);
// Start the thing listening again
server.BeginAccept(new AsyncCallback(AcceptCallback), server);
// Allow the new client to be rejected by the application
ClientInfo c = new ClientInfo(cs, null, null, ClientDirection.Both);
c.server = this;
if(Connect != null){
if(!Connect(this, c)){
// Rejected
cs.Close();
return;
}
}
clients.Add(c);
} catch(ObjectDisposedException) {}
catch(SocketException) {}
}
~Server() { Close(); }
public void Close(){
ArrayList cl2 = new ArrayList();
foreach(ClientInfo c in clients) cl2.Add(c);
foreach(ClientInfo c in cl2) c.Close();
ss.Close();
}
}
public class ByteBuilder {
byte[][] data;
int packsize, used;
public int Length {
get {
int len = 0;
for(int i = 0; i < used; i++) len += data[i].Length;
return len;
}
}
public ByteBuilder() : this(10) {}
public ByteBuilder(int packsize){
this.packsize = packsize; used = 0;
data = new byte[packsize][];
}
public ByteBuilder(byte[] data) {
packsize = 1;
used = 1;
this.data = new byte[][] { data };
}
public void Add(byte[] moredata){ Add(moredata, 0, moredata.Length); }
public void Add(byte[] moredata, int from, int len){
//Console.WriteLine("Getting "+from+" to "+(from+len-1)+" of "+moredata.Length);
if(used < packsize){
data[used] = new byte[len];
for(int j = from; j < from + len; j++)
data[used][j - from] = moredata[j];
used++;
} else {
// Compress the existing items into the first array
byte[] newdata = new byte[Length + len];
int np = 0;
for(int i = 0; i < used; i++)
for(int j = 0; j < data[i].Length; j++)
newdata[np++] = data[i][j];
for(int j = from; j < from + len; j++)
newdata[np++] = moredata[j];
data[0] = newdata;
for(int i = 1; i < used; i++) data[i] = null;
used = 1;
}
}
public byte[] Read(int from, int len){
if(len == 0) return new byte[0];
byte[] res = new byte[len];
int done = 0, start = 0;
for(int i = 0; i < used; i++){
if((start + data[i].Length) <= from){
start += data[i].Length; continue;
}
// Now we're in the data block
for(int j = 0; j < data[i].Length; j++){
if((j + start) < from) continue;
res[done++] = data[i][j];
if(done == len) return res;
}
}
throw new ArgumentException("Datapoints "+from+" and "+(from+len)+" must be less than "+Length);
}
public void Clear(){
used = 0;
for(int i = 0; i < used; i++) data[i] = null;
}
public Parameter GetParameter(ref int index){
Parameter res = new Parameter();
res.Type = Read(index++, 1)[0];
byte[] lenba = Read(index, 4);
index += 4;
int len = ClientInfo.GetInt(lenba, 0, 4);
res.content = Read(index, len);
index += len;
return res;
}
public void AddParameter(Parameter param){ AddParameter(param.content, param.Type); }
public void AddParameter(byte[] content, byte Type){
Add(new byte[]{Type});
Add(ClientInfo.IntToBytes(content.Length));
Add(content);
}
public static String FormatParameter(Parameter p){
switch(p.Type){
case ParameterType.Int:
int[] ia = ClientInfo.GetIntArray(p.content);
StringBuilder sb = new StringBuilder();
foreach(int i in ia) sb.Append(i + " ");
return sb.ToString();
case ParameterType.Uint:
ia = ClientInfo.GetIntArray(p.content);
sb = new StringBuilder();
foreach(int i in ia) sb.Append(i.ToString("X8") + " ");
return sb.ToString();
case ParameterType.String:
return Encoding.UTF8.GetString(p.content);
case ParameterType.Byte:
sb = new StringBuilder();
foreach(int b in p.content) sb.Append(b.ToString("X2") + " ");
return sb.ToString();
default: return "??";
}
}
}
public struct Parameter {
public byte Type;
public byte[] content;
public Parameter(byte[] content, byte type){
this.content = content; Type = type;
}
}
public struct ParameterType {
public const byte Unparameterised = 0;
public const byte Int = 1;
public const byte Uint = 2;
public const byte String = 3;
public const byte Byte = 4;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -