I'm trying to write a remote control application to Windows Phone 7.
All goes OK, but i can not make IP scan over net.
Connected param in Socket class works badly. To use it i need to connect to any IP, then send anymessage - it's Ok. But timeout is too long - about 10 secs(for turned off Pcs).
I need to scan about 256 IPs, and 2560 seconds - is too long.
I tried to write timeout by my self. It works, but after some time application stops.
I can not understand why. No exceptions. Phone just stops attempts to connect and visual studio crashes sometimes.
If there is overflow - where can it be?
Here is some code:
(TryHost is runnung in FOR cycle. Only one start at a time, Searcher.AddHost() runs next iteration of TryHost)
AsynchronousClient:
public void TryHost(string host)
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
DnsEndPoint hostEntry = new DnsEndPoint(host, _port);
// Create a socket and connect to the server
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(SocketEventArg_Completed1);
socketEventArg.RemoteEndPoint = hostEntry;
sock.NoDelay = true;
socketEventArg.UserToken = sock;
try
{
sock.ConnectAsync(socketEventArg);
}
catch (SocketException ex)
{}
}
void SocketEventArg_Completed1(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
ProcessConnect1(e);
break;
case SocketAsyncOperation.SendTo:
connected = false;
ProcessSend1(e);
break;
case SocketAsyncOperation.Receive:
sended = false;
ProcessReceive1(e);
break;
default:
throw new Exception("Problems");
}
}
private void ProcessReceive1(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// Received data from server
string dataFromServer = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
if (dataFromServer.IndexOf("<EOF>") > -1)
{
Searcher.AddHost(dataFromServer);
}
}
else
{
Searcher.AddHost(null);
}
}
private void ProcessSend1(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Socket sock = e.UserToken as Socket;
sended = true;
sock.ReceiveAsync(e);
Thread.Sleep(500);
if (sended)
{
sock.Dispose();
Searcher.AddHost(null);
}
}
else
{
Searcher.AddHost(null);
}
}
private void ProcessConnect1(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
byte[] buffer = Encoding.UTF8.GetBytes("Knock" + "!" + sessionId + "<EOF>");
e.SetBuffer(buffer, 0, buffer.Length);
sock = e.UserToken as Socket;
connected = true;
sock.SendToAsync(e);
e.ConnectSocket.NoDelay = false;
Thread.Sleep(500);
if (connected)
{
sock.Dispose();
}
}
else
{
sock.Dispose();
Searcher.AddHost(null);
}
}
i'm using static class Searcher. UI button starts search from StartSearch() metod wich prepares class to search, and run methods in AsyncClient variable. When AssyncClient request is timed out or answered by host, AssyncClient runs AddHost() method
and Searcher prepares next IP, then start TryHost() again
static Searcher:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Threading;
namespace PivotApp1 {
class PartedIp
{
public string FirstPart;
public string LastPart;
public PartedIp(string first, string last)
{
FirstPart = first;
LastPart = last;
}
}
public class SearchArgs : EventArgs
{
private List<string> message;
public SearchArgs(List<string> msg)
{
message = msg;
}
public List<string> Message
{
get { return message; }
}
}
public static class Searcher
{
static bool searching = false;
static string phoneIp = "";
static string ipTemplate = "";
static int currentLookingIp;
static int stopIp;
static List<string> answers = new List<string>();
static AsynchronousClient newC;
static int chBound = 255;
static int lwBound = 255;
public static event EventHandler SearchComplete = delegate { };
public static void SayItsOver(List<string> message)
{
SearchComplete(null, new SearchArgs(message));
}
static AsynchronousClient searcher;
static string CheckIp()
{
string phoneIp = null;
try
{
MyIPAddress finder = new MyIPAddress();
finder.Find((address) =>
{
phoneIp = address == null ? "Unknown" : address.ToString();
});
}
catch (Exception e)
{
throw new Exception();
}
if (phoneIp == "Unknown")
{
return null;
}
else
{
return phoneIp;
}
}
static PartedIp PrepareForSearch(string phoneIp)
{
IPAddress ipForTest = new IPAddress(10);
if (IPAddress.TryParse(phoneIp, out ipForTest))
{
string[] splittedIp = phoneIp.Split('.');
PartedIp phonePartedIp = new PartedIp(splittedIp[0] + '.' + splittedIp[1] + '.' + splittedIp[2] + '.', splittedIp[3]);
return phonePartedIp;
}
else return null;
}
public static void StartSearch(AsynchronousClient newC)
{
phoneIp = CheckIp();
if (phoneIp != null)
{
searching = true;
newC = newC1;
PartedIp partedIp = PrepareForSearch(phoneIp);
ipTemplate = partedIp.FirstPart;
stopIp = Int32.Parse(partedIp.LastPart);
currentLookingIp = stopIp - 1;
newC.TryHost(ipTemplate + currentLookingIp);
}
else
Deployment.Current.Dispatcher.BeginInvoke(() => {
MessageBox.Show("Error in Ip detection");
});
}
static void NextHost()
{
if (searching)
{
currentLookingIp--;
if (currentLookingIp == 0)
currentLookingIp = 255;
}
}
static public void AddHost(string answer)
{
if (searching)
{
if (answer != null)
{
answers.Add(answer);
}
NextHost();
if (currentLookingIp == stopIp)
{
SayItsOver(answers);
searching = false;
}
else
{
newC.TryHost(ipTemplate + currentLookingIp);
}
}
}
} }
I debugged this a lot of time. My start ip = 192.168.0.103. My Server Ip = 192.168.0.100.
Search working perfectly, until 192.168.0.19(no PCs here). Even if i start my search from 192.168.0.20 it crashed.
Another dead zone is 192.168.0.1 and next 192.168.0.255.
Also - manual starting of TryHost() works fine. Problems begin when I'm trying to automate search.
What's wrong?
I spent a few days on it and just do not know what to do.
Related
So I have searched a lot of areas for this answer and I am confused on what this error is doing. Whenever I press the start server button...
...I get this error "An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll"
My code is quite long but I have no clue what to do...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
private bool isserver = false;
public const int MAXSIZE = 10;
public Form1()
{
InitializeComponent();
clearoutput();
}
TcpListener tcpl = new TcpListener(IPAddress.Parse(getip()), 2546);
List<TcpClient> clients = new List<TcpClient>();
List<string> names = new List<string>();
bool CommandMode = false;
List<string> banlist = new List<string>();
TcpClient Client = new TcpClient();
//client setup
private void button1_Click(object sender, EventArgs e)
{
try {
Output.Text = Output.Text + "You have joined as a client";
Client = new TcpClient();
Client.Connect(IP_address.Text, 2546);
Thread myThread = new Thread(new ParameterizedThreadStart(Listen));
myThread.Start(Client);
//whenever you send a message you must include the next two lines
//Client.GetStream().Write(new byte[] { (byte)Encoding.Unicode.GetByteCount(name + " has joined") }, 0, 1);
//Client.GetStream().Write(Encoding.Unicode.GetBytes(name + " has joined"), 0, Encoding.Unicode.GetByteCount(name + " has joined"));
//the two lines above
Client.GetStream().Write(new byte[] { (byte)Encoding.Unicode.GetByteCount("\\join" + getip()) }, 0, 1);
Client.GetStream().Write(Encoding.Unicode.GetBytes("\\join" + getip()), 0, Encoding.Unicode.GetByteCount("\\join" + getip()));
}
catch { }
IP_address.Visible = false;
Join_btn.Visible = false;
Start_btn.Visible = false;
Output.Visible = true;
Input.Visible = true;
text1.Visible = true;
text1.Visible = true;
}
private void clearoutput()
{
Output.Text = "";
}
//server setup---
private void Start_btn_Click(object sender, EventArgs e)
{
isserver = true;
server_IP_lbl.Text = $"Since you are a server:\nYour ip address is : "+getip();
//if You need a new banlist make sure you click here and allow this
Write_to_output("you are a server");
try
{
StreamReader readerfrban = new StreamReader("banlist");
readerfrban.Close();
Write_to_output("we found a banlist \n no worries");
}
catch
{
Write_to_output("Error- could not find a banlist creating one now");
StreamWriter banlistmaker = new StreamWriter("banlist");
banlistmaker.Close();
}
//open banlist
StreamReader readerforban = new StreamReader("banlist");
string reader = "";
//read all bans in
do
{
reader = readerforban.ReadLine();
if (reader != null)
banlist.Add(reader);
} while (reader != null);
tcpl.Start();
//Thread AcceptSocketsThread = new Thread(AcceptSockets);
//AcceptSocketsThread.Start();
/* while (true)
{
string Message = Console.ReadLine();
if (Message.StartsWith("\\Kick"))
{
Console.Clear();
CommandMode = true;
int clientID = 0;
foreach (TcpClient client in clients)
{
Write_to_output(clientID.ToString() + ") " + names[clientID] + " " + client.Client.RemoteEndPoint);
clientID++;
}
Write_to_output("\n\n Enter the number of the person you want to kick");
TcpClient toRemove = clients[Convert.ToInt32(Console.ReadLine())];
toRemove.Close();
clients.Remove(toRemove);
CommandMode = false;
}
else if (Message.StartsWith("\\Reset"))
{
foreach (TcpClient client in clients)
{
client.Close();
}
clients.Clear();
Write_to_output("KICKED EVERY BODY");
}
else if (Message.StartsWith("\\ban"))
{
Console.Clear();
CommandMode = true;
int clientID = 0;
foreach (TcpClient client in clients)
{
Write_to_output(clientID.ToString() + ") " + names[clientID] + " " + client.Client.RemoteEndPoint);
clientID++;
}
Write_to_output("\n\n Enter the number of the person you want to kick and ban");
TcpClient toRemove = clients[Convert.ToInt32(Console.ReadLine())];
banlist.Add(toRemove.Client.RemoteEndPoint.ToString().Split(new char[] { ':' })[0]);
toRemove.Close();
clients.Remove(toRemove);
CommandMode = false;
}
//starts game
else
{
foreach (TcpClient client in clients)
{
SendMessage(Message, client);
}
}
}*/
IP_address.Visible = false;
Join_btn.Visible = false;
Start_btn.Visible = false;
Output.Visible = true;
Input.Visible = true;
text1.Visible = true;
text1.Visible = true;
}
void SendMessage(string message, TcpClient reciever)
{
try {
reciever.GetStream().Write(new byte[] { (byte)Encoding.Unicode.GetByteCount(message) }, 0, 1);
reciever.GetStream().Write(Encoding.Unicode.GetBytes(message), 0, Encoding.Unicode.GetByteCount(message));
}
catch
{
Write_to_output("Was unable to send to any users error code 1.0.0.0");
}
}
void AcceptSockets()
{
while (true)
{
TcpClient client = tcpl.AcceptTcpClient();
Thread myThread = new Thread(new ParameterizedThreadStart(Listen));
clients.Add(client);
myThread.Start(client);
}
}
void setname(string name)
{
names.Add(name);
}
void Listen(object obj)
{
TcpClient TCPClient = (TcpClient)obj;
while (true)
{
try
{
byte[] fBuffer = new byte[1];
TCPClient.GetStream().Read(fBuffer, 0, 1);
byte[] buffer = new byte[(int)fBuffer[0]];
TCPClient.GetStream().Read(buffer, 0, (int)fBuffer[0]);
string message = Encoding.Unicode.GetString(buffer).Trim();
if (message.StartsWith("\\join"))
{
message = message.Remove(0, 5);
int a = 0;
for (int i = 0; i < banlist.Count; i++)
{
if (message.StartsWith(banlist[i]))
{
a = 1;
}
}
if (a == 0)
{
//int namespaceer = 0;
//foreach (char chars in message)
//{
// namespaceer += 1;
// if (chars == '+')
// break;
//}
// message = message.Remove(0, namespaceer);
}
else
{
//Write_to_output("Person on banlist");
// TcpClient toRemove = clients[Convert.ToInt32(Console.ReadLine())];
//toRemove.Close();
}
}
else
{
foreach (TcpClient client in clients)
{
if (client != TCPClient)
{
SendMessage(message, client);
}
}
if (!CommandMode)
{
Write_to_output(message.Trim());
}
else
{
}
}
}
catch (Exception e)
{
Write_to_output(e.ToString());
}
}
}
static string getip()
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily.ToString() == "InterNetwork")
{
localIP = ip.ToString();
}
}
return localIP;
}
public void Write_to_output(string towrite)
{
//check outputs length
int numLines = 0;
string text = Output.Text;
numLines = Text.Split('\n').Length;
if (numLines == MAXSIZE)
{
Output.Text = towrite;
}
else
{
Output.Text = Output.Text + $"\n" + towrite;
}
}
private void Input_Leave(object sender, EventArgs e)
{
string message = Input.Text;
if (isserver == false)
{
//send client code
SendMessage(message,Client);
}
else
{
//send server code
foreach (TcpClient client in clients)
{
SendMessage(message, client);
}
}
}
}
}
Please help me...
Check if the port TCP 2546 is not busy by another process or code instance on the listening machine.
Or choose another free port to listen to.
Okay so I made a C# TCP reverse proxy server, and for some reason, other TCP reverse proxy servers work but mine does it. In the developer console, mine displays:
WebSocket connection to 'ws://127.0.0.1:1738/' failed: One or more reserved bits are on: reserved1 = 0, reserved2 = 1, reserved3 = 1
Here's the code:
Socket.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
namespace MINA
{
class Sock
{
Socket Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string name = null;
public Sock(string name)
{
this.name = name;
}
public void Connect(string IP, int port, Socket c = null)
{
this.Client.ReceiveTimeout = 0;
if(c != null)
{
this.Client = c;
return;
}
this.Client.Connect(IP, port);
Output.Write("Connected to " + IP + ':' + port, name);
}
public string Send(string data, bool recv = true)
{
try
{
this.Client.Send(Encoding.ASCII.GetBytes(data));
Output.Write(data, name + " | send");
if(recv)
{
return this.Receive();
} else
{
return null;
}
} catch(SocketException)
{
Output.Write("Socket client might not be able to connect to host, and therefore can not send any data.", "fail");
this.Client.Close();
return null;
}
}
public bool isConnected = true;
public string Receive()
{
try
{
byte[] buffer = new byte[2048];
this.Client.Receive(buffer);
string Data = Encoding.ASCII.GetString(buffer).Replace("\0", "");
Output.Write(Data, name + " | recv");
return Data;
}
catch (Exception e)
{
isConnected = false;
this.Client.Close();
return null;
}
}
public void Close()
{
this.Client.Close();
}
}
}
SocketServer.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace MINA
{
class SocketServer
{
int BindPort = 0;
Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public SocketServer(int BindPort = 443)
{
this.BindPort = BindPort;
}
public void BindListen()
{
this.Server.Bind(new IPEndPoint(IPAddress.Any, this.BindPort));
Output.Write("Server bound to port " + this.BindPort, "server");
this.Server.Listen(1000);
Output.Write("Server listening for new connections", "server");
while (true)
{
Socket RCV = this.Server.Accept();
Thread t = new Thread(
new ThreadStart(
delegate
{
Output.Write("Client accepted, bombs fired.", "server");
Sock Receiver = new Sock("RECEIVER");
Receiver.Connect("0", 0, RCV);
Sock Forwarder = new Sock("FORWARDER");
Forwarder.Connect("127.0.0.1", 443);
while (Forwarder.isConnected && Receiver.isConnected)
{
handleReceiverReceive(Forwarder, Receiver);
handleForwarderReceive(Forwarder, Receiver);
}
Forwarder.Close();
Receiver.Close();
}
)
);
t.Start();
}
}
private void handleForwarderReceive(Sock Forwarder, Sock Receiver)
{
string forwarderReceive = Forwarder.Receive();
if (forwarderReceive != null)
{
Receiver.Send(forwarderReceive, false);
}
else
{
Forwarder.Close();
Receiver.Close();
}
}
private void handleReceiverReceive(Sock Forwarder, Sock Receiver)
{
string receiverReceive = Receiver.Receive();
if (receiverReceive != null)
{
Forwarder.Send(receiverReceive, false);
}
else
{
Forwarder.Close();
Receiver.Close();
}
}
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hey guys I am new at the subject of Sockets
and I really need you help.
I am doing system of server and clients (like chat)
but something diffrent, I am doing it with Windows Form Application
in my server : I have list of sockets of all pepole that connect to the server, that already get acception from the server.
And I wanna to do a Timer that every X seconds it will runs on my List and check if the person is still connection I mean in that , that the person still connect on the internet and still can get packages and if not to remove him from the list.
someone can help me in c# how do it??
now at the server if someone is Exit the program Or if the internet is logout how i can check if the Client is out
and if yes so Close his connection?
i Read about TimeOut but how use it??? if it usfull?
Server:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Server
{
public partial class Form1 : Form
{
Socket sck;
static List<Socket> acc;
static List<Thread> thr;
//List<UserAt> thr;
static int port = 9000;
static IPAddress ip;
static Thread NewCon;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
acc = new List<Socket>();
//thr = new List<UserAt>();
thr = new List<Thread>();
NewCon = new Thread(getNewConnection);
//Console.WriteLine("please enter your host port ");
string inputPort = "9000";
try
{
port = Convert.ToInt32(inputPort);
}
catch
{
port = 9000;
}
ip = IPAddress.Parse("127.0.0.1");
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sck.Bind(new IPEndPoint(ip, port));
sck.Listen(0);
NewCon.Start();
}
/// <summary>
/// get new connection from client
/// </summary>
public void getNewConnection()
{
while (true)
{
acc.Add(sck.Accept());
var t = new Thread(() => ReciveMessage(acc.Count-1));
t.Start();
thr.Add(t);
/* UserAt a = new UserAt();
a.index = acc.Count - 1;
a.thread = new Thread(() => ReciveMessage(a.index));
a.thread.Start();
thr.Add(a);
* */
}
}
public void ReciveMessage(int index)
{
while (true)
{
try
{
Thread.Sleep(500);
byte[] Buffer = new byte[255];
int rec = acc[index].Receive(Buffer, 0, Buffer.Length, 0);
Array.Resize(ref Buffer, rec);
//MessageBox.Show(Encoding.Default.GetString(Buffer));
//listBox1.Items.Add(Encoding.Default.GetString(Buffer));
SetText(Encoding.Default.GetString(Buffer));
}
catch
{
// thr[index].thread.Abort();
/*thr.RemoveAt(index);
for (int i = index+1; i < thr.Count;i++ )
{
thr[i].index -= 1;
}*/
break;
}
}
}
delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.listBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.listBox1.Items.Add(text);
}
}
public string getIp()
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
}
}
return localIP;
}
}
}
Client
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class Form1 : Form
{
static string name = "";
static int port = 9000;
static IPAddress ip;
static Socket sck;
public Form1()
{
InitializeComponent();
}
public void ReciveMessage()
{
while (true)
{
Thread.Sleep(500);
byte[] Buffer = new byte[255];
int rec = sck.Receive(Buffer, 0, Buffer.Length, 0);
Array.Resize(ref Buffer, rec);
SetText(Encoding.Default.GetString(Buffer));
//MyChat.Items.Add(Encoding.Default.GetString(Buffer));
}
}
delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.MyChat.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.MyChat.Items.Add(text);
}
}
private void Login_Click(object sender, EventArgs e)
{
name = UserName.Text;
ip = IPAddress.Parse("127.0.0.1");
string inputPort = "9000";
try
{
port = Convert.ToInt32(inputPort);
}
catch
{
port = 9000;
}
try
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sck.Connect(new IPEndPoint(ip, port));
ReciveMes.Enabled = true;
byte[] conmsg = Encoding.Default.GetBytes("<" + name + ">" + " connected");
sck.Send(conmsg, 0, conmsg.Length, 0);
SendToServer.Enabled = true;
}
catch
{
MessageBox.Show("חיבור נכשל");
}
}
private void SendToServer_Click(object sender, EventArgs e)
{
byte[] sdata = Encoding.Default.GetBytes("<" + name + ">" + MyMessage.Text);
sck.Send(sdata, sdata.Length, 0);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if(SendToServer.Enabled)
{
byte[] sdata = Encoding.Default.GetBytes("<" + name + ">" + "Is Quit");
sck.Send(sdata, sdata.Length, 0);
}
}
}
}
I've looked around links related. I can't find any. Help me, please.
Here's my code.(VS2010)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://whatismyipaddress.com/");
request.Proxy = new WebProxy("127.0.0.1:9150");
request.KeepAlive = false;
try
{
using (var response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
string temp = reader.ReadToEnd();
MessageBox.Show(temp);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
That brings error message like this.
(501) Not implemented.
And Tor says.
Socks version 71 not recognized.(Tor is not a http proxy)
What's wrong?Someone help me.
Unfortunately after some digging TOR is not a HTTP Proxy. It's a SOCKS proxy, you can use something like Privoxy that allows sock forwarding.
using Tor as Proxy
How to use Privoxy with TOR: http://www.privoxy.org/faq/misc.html#TOR
I created the following class (HttpOverSocksProxy) to route my http requests through to the Tor socks proxy.
It does this by:
listening on a local port (eg 127.0.0.1:9091) for incoming http requests
grabs the host from the headers of these requests
opens up a connection through Tor to this host
copys all data (GET\POST,headers,body) from the source connection through to the Tor connection and visa versa
Http requests are then made as you have done above but with the WebProxy set to the http\socks proxy in the above case this would be 127.0.0.1:9091
Note that https requests are not supported, you will recieve a 400 error from the webserver
I am using the Mentalis class ProxySocket to wrap up the Socks connection as a standard Socket
http://www.mentalis.org/soft/class.qpx?id=9
This code has not being thoroughly tested but so far it works fine.
HttpOverSocksProxy Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using Org.Mentalis.Network.ProxySocket;
using System.IO;
namespace ConsoleApplication1
{
/*
* HTTPS is not supported, it will probably result in a (400) 'Bad Request' response.
*/
public class HttpOverSocksProxy
{
private class Connection
{
public IPLocation host_loc;
public bool host_found = false;
public bool host_connected = false; //if have_found==true && host_connected==false then we are currently connecting to the host
public long host_last_read_pos = 0;
public NetworkStream client_stream = null;
public TcpClient client_tcp = null;
public NetworkStream host_stream = null;
public ProxySocket host_socket = null;
public byte[] client_buf_ary = null;
public byte[] host_buf_ary = null;
public MemoryStream buf_str = null;
public Connection(NetworkStream str,TcpClient client,int buffer_size)
{
this.client_stream = str;
this.client_tcp = client;
this.host_buf_ary = new byte[buffer_size];
this.client_buf_ary = new byte[buffer_size];
this.buf_str = new MemoryStream(buffer_size);
}
}
private struct IPLocation
{
public string host;
public int port;
public IPLocation(string host, int port)
{
this.host = host;
this.port = port;
}
}
private TcpListener _tcp_server;
private List<Connection> _connections = new List<Connection>();
public IPEndPoint EndPoint_Source_Http { get; private set; }
public IPEndPoint EndPoint_Destination_Socks { get; private set; }
public ProxyTypes SocksProxyType { get; private set; }
public int Buffer_Size { get; private set; }
public HttpOverSocksProxy(IPEndPoint http_listen, IPEndPoint socks_proxy, ProxyTypes socks_proxy_type, int buffer_size = 1024*4)
{
this.EndPoint_Source_Http = http_listen;
this.EndPoint_Destination_Socks = socks_proxy;
this.SocksProxyType = socks_proxy_type;
this.Buffer_Size = buffer_size;
}
public void Start()
{
_tcp_server = new TcpListener(EndPoint_Source_Http);
_tcp_server.Start();
_tcp_server.BeginAcceptTcpClient(Client_Accept, _tcp_server);
}
public void Stop()
{
lock (_connections)
{
_tcp_server.Stop();
_connections.ForEach(a => Close(a));
_connections.Clear();
}
}
private void Client_Accept(IAsyncResult result)
{
TcpListener tcp_server = result.AsyncState as TcpListener;
if (tcp_server != null)
{
TcpClient tcp_client = tcp_server.EndAcceptTcpClient(result);
if (tcp_client != null)
{
Connection conn = new Connection(tcp_client.GetStream(), tcp_client, Buffer_Size);
lock (_connections)
{
_connections.Add(conn);
}
conn.client_stream.BeginRead(conn.client_buf_ary, 0, Buffer_Size, Client_Write, conn);
}
tcp_server.BeginAcceptTcpClient(Client_Accept, tcp_server);
}
}
private void Client_Write(IAsyncResult result)
{
Connection conn = result.AsyncState as Connection;
if (conn != null)
{
try
{
int len = conn.client_stream.EndRead(result);
if (len == 0) // Client has closed the connection
{
Close(conn);
}
else
{
lock (conn)
{
if (conn.host_connected)
{
try
{
conn.host_stream.Write(conn.client_buf_ary, 0, len); //we want this to block
}
catch (Exception e_h)
{
if (!Handle_Disposed(e_h, conn))
throw;
}
}
else
conn.buf_str.Write(conn.client_buf_ary, 0, len);
if (!conn.host_found)
OpenHostConnection(conn);
conn.client_stream.BeginRead(conn.client_buf_ary, 0, Buffer_Size, Client_Write, conn);
}
}
}
catch (Exception e_c)
{
if (!Handle_Disposed(e_c, conn))
throw;
}
}
}
private void OpenHostConnection(Connection conn)
{
if (conn.host_found)
throw new Exception("Already have host"); //should never happen
#region Get Host from headers
{
MemoryStream str_mem = conn.buf_str;
str_mem.Position = conn.host_last_read_pos;
string raw_host_line;
while ((raw_host_line = ReadLine(str_mem, ASCIIEncoding.ASCII)) != null)
{
conn.host_last_read_pos = str_mem.Position;
if (raw_host_line.Length == 0)
throw new Exception("Failed to find Host in request headers");
int idx_split;
if ((idx_split = raw_host_line.IndexOf(':')) > 0 && idx_split < raw_host_line.Length)
{
string key = raw_host_line.Substring(0, idx_split);
string val = raw_host_line.Substring(idx_split + 1).Trim();
if (key.Equals("host", StringComparison.InvariantCultureIgnoreCase))
{
string[] host_parts = val.Split(':');
if (host_parts.Length == 1)
{
conn.host_loc = new IPLocation(host_parts[0], 80);
}
else if (host_parts.Length == 2)
{
conn.host_loc = new IPLocation(host_parts[0], Int32.Parse(host_parts[1]));
}
else
throw new Exception(String.Format("Failed to parse HOST from '{0}'", raw_host_line));
conn.host_found = true;
}
}
}
str_mem.Seek(0,SeekOrigin.End);
}
#endregion
#region Open Host Connection
{
if (conn.host_found)
{
try
{
ProxySocket skt = new ProxySocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
skt.ProxyEndPoint = EndPoint_Destination_Socks;
skt.ProxyType = ProxyTypes.Socks5;
conn.host_socket = skt;
if (conn.host_loc.port == 443)
Console.WriteLine("HTTPS is not suported.");
skt.BeginConnect(conn.host_loc.host, conn.host_loc.port, Host_Connected, conn);
}
catch (ObjectDisposedException e)
{
if (!Handle_Disposed(e, conn))
throw;
}
}
}
#endregion
}
private void Host_Connected(IAsyncResult result)
{
Connection conn = result.AsyncState as Connection;
if (conn != null)
{
lock (conn) //Need to set up variables and empty buffer, cant have the Client writing to the host stream during this time
{
try
{
conn.host_socket.EndConnect(result);
conn.host_stream = new NetworkStream(conn.host_socket);
conn.host_connected = true;
conn.buf_str.Position = 0;
conn.buf_str.CopyTo(conn.host_stream);
conn.host_stream.BeginRead(conn.host_buf_ary, 0, Buffer_Size, Host_Write, conn);
}
catch (Exception e)
{
if (!Handle_Disposed(e, conn))
throw;
}
}
}
}
private void Host_Write(IAsyncResult result)
{
Connection conn = result.AsyncState as Connection;
if (conn != null)
{
try
{
int len = conn.host_stream.EndRead(result);
if (len == 0)
{
Close(conn);
}
else
{
try
{
conn.client_stream.Write(conn.host_buf_ary, 0, len); //we want this to block
}
catch (Exception e_c)
{
if (!Handle_Disposed(e_c, conn))
throw;
}
conn.host_stream.BeginRead(conn.host_buf_ary, 0, Buffer_Size, Host_Write, conn);
}
}
catch (Exception e_h)
{
if (!Handle_Disposed(e_h, conn))
throw;
}
}
}
private void Close(Connection conn)
{
lock (conn)
{
try
{
if (conn.host_connected)
conn.host_socket.Close();
}
catch { }
try
{
conn.client_tcp.Close();
}
catch { }
}
}
private bool Handle_Disposed(Exception exp,Connection conn)
{
if (exp is ObjectDisposedException || (exp.InnerException != null && exp.InnerException is ObjectDisposedException))
{
Close(conn);
return true;
}
else
return false;
}
private string ReadLine(MemoryStream str,Encoding encoding) // Reads a line terminated by \r\n else returns resets postion and returns null
{
long idxA= str.Position; //first position of line
long idxB =-1; //position after last char
int b_last = str.ReadByte();
int b_this = 0;
for (long i = 1; i < str.Length; i++)
{
b_this = str.ReadByte();
if (b_this == '\n' && b_last == '\r')
{
idxB = str.Position;
str.Position = idxA;
int len = (int)(idxB - idxA);
byte[] buf = new byte[len];
str.Read(buf, 0, len);
return encoding.GetString(buf);
}
else
b_last = b_this;
}
str.Position = idxA;
return null;
}
}
}
Example Usage:
static void Main(string[] args)
{
IPAddress localhost = IPAddress.Parse("127.0.0.1");
IPEndPoint src_http = new IPEndPoint(localhost, 9091);
IPEndPoint des_tor = new IPEndPoint(localhost, 9050);
HttpOverSocksProxy proxy = new HttpOverSocksProxy(src_http, des_tor, ProxyTypes.Socks5);
proxy.Start();
WebClientExt client = new WebClientExt();
client.Proxy = new WebProxy(src_http.ToString(), false);
string res = client.DownloadString("http://en.wikipedia.org/wiki/HTTP_compression");
Console.WriteLine(res);
Console.WriteLine("Done");
Console.ReadKey();
}
I had to make small modifications to the class ProxySocket so that the async calls retuned my state object. Not sure why it didn't already.
I can't post the updated code due to a character limit but I can describe them quickly enough:
In ProxySocket.BeginConnect set this.State = state
In ProxySocket.OnHandShakeComplete set AsyncResult.AsyncState = State.
The property IAsyncProxyResult.AsyncState was updated so the there was a setter with privacy 'internal'
This is one of my first issues. Whenever I exit out the program, tcpClient.Connect() takes forever to close. I've tried a ton of things, and none of them seem to work.
Take a look at the CreateConnection() thread, if the client isn't connected yet... and I close the program, it takes forever to close. If it IS connected, it closes immediately. I know this can be done with some kind of timeout trick, but i've tried a few and none of them worked.
Please provide a code example if you can.
Also, is there any good tutorial out there for C# on reading/writing the actual bytes with a buffer instead of this version that just does masterServer.writeLine() and masterServer.readline() or are they both just as efficient?
If you see anything else to help me improve this... by all means, go ahead. I'm trying to teach myself how to do this and I have no help, so don't let me go on doing something wrong if you see it!!! Thanks guys!
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;
using System.IO;
namespace RemoteClient
{
public partial class Form1 : Form
{
private int MyPort = 56789;
private IPAddress myIp = IPAddress.Parse("210.232.115.79");
private IPAddress serverIp = IPAddress.Parse("72.216.18.77"); // Master Server's IP Address
public static TcpClient masterServer = new TcpClient();
private StreamWriter responseWriter;
private StreamReader commandReader;
private Thread connectionThread;
private Thread commandsThread;
private bool RequestExitConnectionThread { get; set; }
private delegate void AddMessageDelegate(string message, int category);
private delegate void ConnectedDelegate();
private bool isConnected { get; set; }
public Form1()
{
InitializeComponent();
isConnected = false;
}
private void LogMessage(string message, int category)
{
if (category == 1)
{
ListViewItem item = new ListViewItem(message);
item.BackColor = Color.LightGreen;
item.UseItemStyleForSubItems = true;
Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString());
}
if (category == 2)
{
ListViewItem item = new ListViewItem(message);
item.BackColor = Color.Orange;
item.UseItemStyleForSubItems = true;
Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString());
}
if (category == 3)
{
ListViewItem item = new ListViewItem(message);
item.BackColor = Color.Yellow;
item.UseItemStyleForSubItems = true;
Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString());
}
if (category == 0)
{
Log.Items.Add(message).SubItems.Add(DateTime.Now.ToString());
}
}
private void Connected()
{
LogMessage("Found and Accepted Master Server's connection. Waiting for reply...",1);
Status.Text = "Connected!";
Status.ForeColor = Color.Green;
commandsThread = new Thread(new ThreadStart(RecieveCommands));
sendClientInfo();
}
private void exitButton_Click(object sender, EventArgs e)
{
Disconnect();
exitButton.Enabled = false;
exitButton.Text = "Closing...";
if (connectionThread != null)
{
while (connectionThread.IsAlive)
{
Application.DoEvents();
}
}
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
Connect();
}
private void Disconnect()
{
RequestExitConnectionThread = true;
if (masterServer != null)
masterServer.Close();
if (connectionThread != null)
connectionThread.Abort();
LogMessage("Closing Client. Please wait while Program threads end.", 2);
}
private void Disconnected()
{
Status.Text = "Disconnected";
Status.ForeColor = Color.Red;
Connect();
}
private void Connect()
{
LogMessage("Attempting to connect to Master Server...", 1);
connectionThread = new Thread(new ThreadStart(CreateConnection));
connectionThread.Start();
}
private void CreateConnection()
{
int i = 1;
bool success = false;
while (!success)
{
try
{
using (masterServer = new TcpClient())
{
IAsyncResult result = masterServer.BeginConnect(serverIp, MyPort, null, null);
success = result.AsyncWaitHandle.WaitOne(1000, false);
}
if (success)
{
BeginInvoke(new ConnectedDelegate(this.Connected), new object[] {});
break;
}
else
{
Thread.Sleep(2000);
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connection Retry # " + i.ToString() + ". Master Server hasn't been started yet.", 3 });
}
}
catch
{
MessageBox.Show("Error!");
}
i++;
}
}
private void RecieveCommands()
{
MessageBox.Show("Hello!");
commandReader = new StreamReader(masterServer.GetStream());
string CommandResponse = commandReader.ReadLine();
string Command = null;
if (CommandResponse != null)
MessageBox.Show("Recieved Command that was NOT null!");
if (CommandResponse != null)
{
MessageBox.Show("Recieved null response!");
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: Recieved Null response.", 1 });
Disconnected();
}
else if (CommandResponse.StartsWith("0"))
{
MessageBox.Show("Recieved 0 as a response!");
Command = CommandResponse.Substring(2).Trim();
isConnected = false;
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: " + Command, 1 });
}
else if (CommandResponse.StartsWith("1"))
{
MessageBox.Show("Recieved 1 as a response!");
isConnected = true;
BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connected to Master Server Successfully.", 1 });
}
}
//************************** RESPONSE'S BELOW HERE ************************* \\
private void sendClientInfo()
{
responseWriter = new StreamWriter(masterServer.GetStream());
responseWriter.WriteLine(myIp.ToString());
responseWriter.Flush();
}
}
}
Sorry, after testing it: NO, it does not use an async waithandle, it blocks the process :(
I prefer this solution, which also blocks the process but only by the period you specify, in this case 5 seconds:
using (TcpClient tcp = new TcpClient())
{
IAsyncResult ar = tcp.BeginConnect("127.0.0.1", 80, null, null);
System.Threading.WaitHandle wh = ar.AsyncWaitHandle;
try
{
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false))
{
tcp.Close();
throw new TimeoutException();
}
tcp.EndConnect(ar);
}
finally
{
wh.Close();
}
}
From: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/2281199d-cd28-4b5c-95dc-5a888a6da30d
The following example uses both async connection and async timeout control:
var tcp = new TcpClient();
var ar = tcp.BeginConnect(Ip, Port, null, null);
Task.Factory.StartNew(() =>
{
var wh = ar.AsyncWaitHandle;
try
{
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false))
{
// The logic to control when the connection timed out
tcp.Close();
throw new TimeoutException();
}
else
{
// The logic to control when the connection succeed.
tcp.EndConnect(ar);
}
}
finally
{
wh.Close();
}
});
connect with timeout of 2000 ms:
AutoResetEvent connectDone = new AutoResetEvent( false );
TcpClient client = new TcpClient();
client.BeginConnect(
"127.0.0.1", 80,
new AsyncCallback(
delegate( IAsyncResult ar ) {
client.EndConnect( ar );
connectDone.Set();
}
), client
);
if( !connectDone.WaitOne( 2000 ) ) {
Console.WriteLine( "network connection failed!" );
Environment.Exit( 0 );
}
Stream stream = client.GetStream();
Adding a check within your connection process to cancel it if the program is exiting should help.
Try adding this in CreateConnection() inside your while(!success) loop but before your try block:
if(RequestExitConnectionThread)
{
break;
}
Here's an example of an asynchronous BeginConnect() call:
myTcpClient.BeginConnect("localhost", 80, OnConnect, null);
OnConnect function:
public static void OnConnect(IAsyncResult ar)
{
// do your work
}