in my program in c#, i need to connect to a website by a specified ip.for this I use ServicePoint.BindIPEndPointDelegate,but it doesn't work. I searched and found this:
when server supports ipv6, we try to establish connection with server using its ipv6 address. But an ipv4 address is specified in the callback. Since the socket has already been created with AddressFamily.InterNetworkv6 when the delegate is called, the bind to an IPv4 address fails. So the delegate is called again. But the same endpoint is returned so the bind fails again. This repeats Integer.MaxValue times and then OverflowException is thrown. Note Integer.MaxValue is a really big value and it looks as though the code has gone to an infinite loop.
now how can I solve this problem? I need to connect with specified ip.
the code :
private void button1_Click(object sender, EventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.scopus.com");
request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream data = response.GetResponseStream();
StreamReader reader = new StreamReader(data);
var result = reader.ReadToEnd();
reader.Close();
response.Close();
txtResult.Text = result;
}
public static IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
IPAddress address=IPAddress.Parse("77.81.99.66");
if (retryCount == 5)
return null;
return new IPEndPoint(address, 7070);
}
Related
I have hardware that sends information to the address 192.168.0.255 at approximately 5 second intervals (In the following image, the Wireshark software showing the device with IP address 192.168.0.241 sending the message "Hallo" to the address 192.168.0.255 on port 7000):
On the other hand, I have a desktop app made in C # that tries to read that information as follows:
int PORT = 7000;
udpClient = new UdpClient();
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, PORT));
private async Task<string> getData()
{
try
{
var from = new IPEndPoint(0, 0);
while (true)
{
var recvBuffer = udpClient.Receive(ref from);
string result= Encoding.UTF8.GetString(recvBuffer);
if (result != null && resultado.Length > 0)
{
return result;
}
}
}
...
}
It doesn't work (udpClient.Receive never returns information, it is similar to that there is no socket information yet), but if I open a software tool from my PC that allows me to write information to a UDP scoket, the code works wonderfully (udpClient.Receive captures the sent information.)
Any suggestions or comments?
UdpClient client;
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, PORT);
private void Connect()
{
client = new UdpClient(7000);
client.Connect(endPoint);
client.BeginReceive(ReceiveCallback, null);
}
private void ReceiveCallback(IAsyncResult _result)
{
try
{
byte[] _data = client.EndReceive(_result, ref endPoint);
socket.BeginReceive(ReceiveCallback, null);
if (_data.Length < 4)
{
//disconnected
return;
}
//now data is anything received and if you want to view it as a string do:
string result = Encoding.Default.GetString(data);
//you can also convert it to other things like ints, float, etc
}
catch
{
//disconnected
}
}
Thanks to #MarkusSafar's suggestion, I put the desktop app on another PC and from there it manages to capture the hardware message. I'm not sure why it doesn't work on my PC, but the next step is to test this same code for an app developed for Android (Xamarin), I hope it works there too.
Hello I am developing sample application for demonstration of udp client to send data from client to server. I have created console application and below is my code.
class Program
{
static void Main(string[] args)
{
senddata();
while (true)
{
try {
UdpClient udpClient = new UdpClient(9999);
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
string result;
result = returnData.ToString();
}
catch(Exception e)
{
}
}
void senddata()
{
UdpClient udpClient = new UdpClient(9999);
udpClient.Connect("10.170.84.163", 9999);
Byte[] senddata1 = Encoding.ASCII.GetBytes("Hello World");
udpClient.Send(senddata1, senddata1.Length);
}
}
}
whenever Byte[] receiveBytes is executed i get my empty black screen and nothing is going to happen. Can someone tell me how to fix this? Any help would be appreciated. Thank you.
There are several issues here:
You send data to udp port (via senddata()) before starting a listener on that port, and you do this only once, so there is no chance listener might receive it.
There is no need to bind UdpClient to specific port when sending data, especially to the same port on which you are listening with another UdpClient. Just use UdpClient udpClient = new UdpClient(); to let it use any available port for sending.
Since you are testing - there is no need to send data to your external ip, send to loopback interface instead: udpClient.Connect(IPAddress.Loopback, 9999);.
UdpClient implements IDisposable, so dispose it when you are done.
Your while (true) loop will not work, because you don't dispose UdpClient, so on second iteration of the loop, second UdpClient will try to bind to the same 9999 port and fail, because there is already listener (which you didn't dispose) on that same port.
Your code with fixes above (obviously that is not "production" code so I won't add things like cancellation and so on, only fixes to be able to see message is coming):
static void senddata() {
// send message every 100 ms
while (true) {
// wrap in using
using (UdpClient udpClient = new UdpClient()) {
// loopback
udpClient.Connect(IPAddress.Loopback, 9999);
Byte[] senddata1 = Encoding.ASCII.GetBytes("Hello World");
udpClient.Send(senddata1, senddata1.Length);
}
Thread.Sleep(100);
}
}
static void Main(string[] args) {
// run sending in background
Task.Run(() => senddata());
try {
// wrap in using
using (UdpClient udpClient = new UdpClient(9999)) {
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
// move while loop here
while (true) {
// this blocks until message is received
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine(returnData);
}
}
}
catch (Exception e) {
// do something meaningful
}
}
It doesn't look like you're outputting the received string.
Something like this....
string result;
result = returnData.ToString();
Console.WriteLine(result);
Try changing the following:
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
To use the port 9999 rather than a random port. I'm honestly somewhat surprised that doesn't throw an exception.
Note that binding to a random port as a server is not atypical but the remote end will need some way to discover that random port I..E. the way ftp uses a second port for actual file data transfer, that port number is sent as part of the message starting the transfer.
Im trying to build a small compact telnet tool
therefor I've decided to tackle the sending without waiting for response part first
the problem is that no matter which guide I use I just cant make it work
what am I missing here ??
public void SendTelnetCommand(string Command , string IPofAP)
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(IPofAP), 23);
TcpClient tcpSocket;
tcpSocket = new TcpClient(endpoint);
if (!tcpSocket.Connected) return;
byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(Command);
tcpSocket.GetStream().Write(buf, 0, buf.Length);
if (tcpSocket.Connected) tcpSocket.Close();
}
while debuging I get An unhandled exception of type 'System.Net.Sockets.SocketException' in System.dll
What's the message of the exception? Any inner exceptions? Are you using the correct IP address (IPv4 or IPv6?)? Also, you have to read from the stream as well.
However, your issue is most likely using the wrong TcpClient constructor. The one that takes the endpoint is a listener, not a client. You have to use the hostname + port overload.
That is, try this:
public void SendTelnetCommand(string Command, string IPofAP)
{
TcpClient tcpSocket = new TcpClient(IPofAP, 23);
if (!tcpSocket.Connected) return;
byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(Command);
tcpSocket.GetStream().Write(buf, 0, buf.Length);
if (tcpSocket.Connected) tcpSocket.Close();
}
You can also use the IPEndPoint to connect to a server, however, you have to use the parameter-less constructor, and call tcpSocket.Connect(endpoint);
I have a simple C# Windows Service that should respond "OK" to GET requests on port 8080.
Everything works fine, with one simple itch...
Every single request made to the service stays in TIME_WAIT.
Am I missing something, I've looked around and most samples I've seen on HTTPListeners and Windows Services are doing it in a similar fashion?!
private HttpListener _listener;
protected override void OnStart(string[] args)
{
_listener = new HttpListener();
_listener.Prefixes.Add("http://*:8080/");
_listener.Start();
_listener.BeginGetContext(new AsyncCallback(OnRequestReceive), _listener);
}
protected override void OnStop()
{
_listener.Stop();
}
private void OnRequestReceive(IAsyncResult result)
{
if (!_listener.IsListening)
return;
//Get context for a request.
HttpListenerContext context = _listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
//Obtain a response object.
HttpListenerResponse response = context.Response;
response.ContentType = "application/json";
response.KeepAlive = false;
//Our return message...
string responseString = "OK";
//Construct the response.
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
Stream output = response.OutputStream;
response.ContentLength64 = buffer.Length;
output.Write(buffer, 0, buffer.Length);
//Close and send response
try
{
output.Flush();
output.Close();
response.Close();
}
finally
{
//Wait for another request
_listener.BeginGetContext(new AsyncCallback(OnRequestReceive), _listener);
}
}
Edit: Fixed Local declaration of _listener.
Thanks to rene for pointing out the correct direction...
TIME-WAIT
(either server or client) represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request. [According to RFC 793 a connection can stay in TIME-WAIT for a maximum of four minutes known as a MSL (maximum segment lifetime).]
For anyone else who wants to change this behavior:
The TIME_WAIT period is configurable by modifying the following DWORD registry setting that represents the TIME_WAIT period in seconds.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters\TcpTimedWaitDelay
I'm trying to make a simple C# web server that, at this stage, you can access via your browser and will just do a "Hello World".
The problem I'm having is that the server can receive data fine - I get the browser's header information - but the browser doesn't receive anything I send. Furthermore, I can only connect to the server by going to localhost (or 127.0.0.1). I can't get to it by going to my IP and it's not a network setting because Apache works fine if I run that instead. Also, I'm using a port monitoring program and after I attempt a connection from a browser, the process's port gets stuck in a TIME_WAIT state even though I told the connection to close and it should be back to LISTEN.
Here's the relevant code. A couple calls might not make sense but this is a piece of a larger program.
class ConnectionHandler
{
private Server server;
private TcpListener tcp;
private ArrayList connections;
private bool listening;
private Thread listeningThread;
public Server getServer()
{
return server;
}
private void log(String s, bool e)
{
server.log("Connection Manager: " + s, e);
}
private void threadedListen()
{
while (listening)
{
try
{
TcpClient t = tcp.AcceptTcpClient();
Connection conn = new Connection(this, t);
}
catch (NullReferenceException)
{
log("unable to accept connections!", true);
}
}
log("Stopped listening", false);
}
public void listen()
{
log("Listening for new connections", false);
tcp.Start();
listening = true;
if (listeningThread != null && listeningThread.IsAlive)
{
listeningThread.Abort();
}
listeningThread = new Thread(new ThreadStart(
this.threadedListen));
listeningThread.Start();
}
public void stop()
{
listening = false;
if (listeningThread != null)
{
listeningThread.Abort();
log("Forced stop", false);
}
log("Stopped listening", false);
}
public ConnectionHandler(Server server)
{
this.server = server;
tcp = new TcpListener(new IPEndPoint(
IPAddress.Parse("127.0.0.1"), 80));
connections = new ArrayList();
}
}
class Connection
{
private Socket socket;
private TcpClient tcp;
private ConnectionHandler ch;
public Connection(ConnectionHandler ch, TcpClient t)
{
try
{
this.ch = ch;
this.tcp = t;
ch.getServer().log("new tcp connection to "
+ this.tcp.Client.RemoteEndPoint.ToString(), false);
NetworkStream ns = t.GetStream();
String responseString;
Byte[] response;
Int32 bytes;
responseString = String.Empty;
response = new Byte[512];
bytes = ns.Read(response, 0, response.Length);
responseString =
System.Text.Encoding.ASCII.GetString(response, 0, bytes);
ch.getServer().log("Received: " + responseString);
String msg = "<html>Hello World</html>";
String fullMsg = "HTTP/1.x 200 OK\r\n"
+ "Server: Test Server\r\n"
+ "Content-Type: text/html; "
+ "charset=UTF-8\r\n"
+ "Content-Length: " + msg.Length + "\r\n"
+ "Date: Sun, 10 Aug 2008 22:59:59 GMT"
+ "\r\n";
nsSend(fullMsg, ns);
nsSend(msg, ns);
ns.Close();
tcp.Close();
}
catch (ArgumentNullException e)
{
ch.getServer().log("connection error: argument null exception: " + e);
}
catch (SocketException e)
{
ch.getServer().log("connection error: socket exception: " + e);
}
}
private void nsSend(String s, NetworkStream ns)
{
Byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
ns.Write(data, 0, data.Length);
ns.Flush();
ch.getServer().log("Sent: " + s);
}
}
Does anyone have any ideas? It feels like it's gotta be something stupid on my part but I just don't know what. I'd really appreciate any insight
You might like to know that you can use HttpListener to write a basic web-server very easily - this deals with most of the painful bits, letting you concentrate on writing the actual code. The MSDN page gives an example.
Note that this uses HTTP.SYS, which is good - but means that non-admins need to be explicitly given access to open ports; on xp you can do this with httpcfg; on vista you can use netsh. See here for more.
One thing which isn't a problem at the moment but might be later on is that your content length is based on the Unicode length of the message string, not the binary length.
There's also rather a lot going on in the Connection constructor - stuff that really doesn't belong in a constructor at all, IMO. It also doesn't close things if exceptions occur.
Have you looked at what's going on in a network tracer like WireShark? That would be the easiest way of seeing whether any data is getting sent back to the client.
Alternatively, post a short but complete version of your code which we can compile and run ourselves.
Maybe I'm just missing something but the reason you can only connect on localhost is because the IP you are listening on is 127.0.0.1, this makes the TCPListener only listen on that IP address. And I don't see anywhere you are calling any client disconnect, the TCPListener is a blocking call, so it sits there forever until a connection is made. In my past experience with TCP/IP and the TCPListener, TCPClient classes there is not much of a way to force the listener to drop it's connection until you drop the client connection. Calling TCPListener.Abort() doesn't drop the client connection which keeps the port blocked up.
For anyone in similar situation where you want to access you C# server from the local network ip address then you will need to listen to address 0.0.0.0 meaning listen on all ip addresses not a specific one like 127.0.0.1 etc.