I using Socket to get http response from www.google.com.vn
TcpClient c = new TcpClient();
IPAddress ip = IPAddress.Parse("74.125.128.94"); // www.google.com.vn
IPEndPoint remoteEP = new IPEndPoint(ip, 80);
c.Connect(remoteEP);
StreamReader sr = new StreamReader(c.GetStream());
String s = sr.ReadToEnd();
Console.WriteLine(s);
I do not get any results out. What's problem?
You're not actually making a request - you're just connecting to the port.
Either write an HTTP request to the socket, or (preferrably) use WebRequest or WebClient so that you don't end up implementing an HTTP client yourself...
Related
We are using C# Socket in Unity to connect to our server. Using proxy is crucial for our use case, unfortunately there is no direct support for proxy in Socket. We are using both TCP and UDP sockets at the same time to exchange data between our app and the server.
Based on this question I'm able to connect through the proxy with first TCP socket, but when I try to connect through the same proxy with second UDP socket, I receive this exception on line socket.Receive(receiveBuffer):
System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host.
ErrorCode = 10054
SocketErrorCode = ConnectionReset
Does it means that the first TCP ws closed because ther can be only one connection at the same time?
I'm using Fiddler to test this scenario. I do not see the second UDP connection in its log.
Is it possible to connect through single proxy with more than one socket from the same app (process)?
Is there some settings in Fiddler that should be changed? Am I missing something?
My simplified code:
class ConnectorExample
{
public class ProxyConfig
{
public string server; // http://127.0.0.1:8888
public string username;
public string password;
public Uri serverUri => new Uri(server);
}
void Connect(IPAddress ipAddress, int tcpPort, int udpPort, ProxyConfig proxyConfig)
{
IPEndPoint remoteTcpEndPoint = new IPEndPoint(ipAddress, tcpPort);
IPEndPoint remoteUdpEndPoint = new IPEndPoint(ipAddress, udpPort);
Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket udpSocket = new Socket(tcpSocket.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
// TCP socket
ConnectThroughProxy(proxyConfig, tcpSocket, remoteTcpEndPoint);
// UDP Socket
// Bind UDP to a free port
udpSocket.Bind(new IPEndPoint(((IPEndPoint) tcpSocket.LocalEndPoint).Address, 0));
ConnectThroughProxy(proxyConfig, udpSocket, remoteUdpEndPoint);
}
// Returns true if connection through the proxy succeeded
private bool ConnectThroughProxy(ProxyConfig proxyConfig, Socket socket, IPEndPoint destination)
{
Uri proxyUri = proxyConfig.serverUri;
string username = proxyConfig.username;
string password = proxyConfig.password;
// Connect to the proxy
socket.Connect(proxyUri.Host, proxyUri.Port);
// Authentication
string auth = string.Empty;
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
string credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"));
auth = $"Proxy-Authorization: Basic {credentials}";
}
// Connect to the destination
// string connectString = $"CONNECT {destination.Address}:{destination.Port} HTTP/1.1{Environment.NewLine}{auth}{Environment.NewLine}{Environment.NewLine}";
string hostAddress = $"{destination.Address}:{destination.Port}";
string connectString = $"CONNECT {destination.Address}:{destination.Port} HTTP/1.1{Environment.NewLine}Host: {hostAddress}{Environment.NewLine}{auth}{Environment.NewLine}{Environment.NewLine}";
byte[] connectMessage = Encoding.UTF8.GetBytes(connectString);
socket.Send(connectMessage);
byte[] receiveBuffer = new byte[1024];
int received = socket.Receive(receiveBuffer); // Exception for second UDP socket
string response = ASCIIEncoding.ASCII.GetString(receiveBuffer, 0, received);
// Response content sample:
// HTTP/1.1 200 Connection Established
// TODO: Should we check for string: "HTTP/1.1 200" ? Checking just "200" seems to be quite weak check.
bool connected = response.Contains("200");
return connected;
}
}
EDIT:
Perhaps the correct question is: Is it possible to use proxy for UDP connections?
So far I have tried this
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.ServicePoint.BindIPEndPointDelegate = delegate
{
IPAddress ip = IPAddress.Parse("127.0.0.1");
return new IPEndPoint(ip, 0);
};
request.Method = WebRequestMethods.Ftp.Rename;
The issue is FtpWebRequest class has limited functionality where as FtpClient is more versatile. How do I bind local IpEndpoint to FtpClient class in FluentFTP library? Any suggestions?
It does not seem to be possible.
FluentFTP let's you only to choose what IP version you want to use by InternetProtocolVersions.
I'm trying to make httpwebrequest through socks5 proxy, using mentalis library.
ProxySocket s = new ProxySocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// set the proxy settings
s.ProxyEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
s.ProxyType = ProxyTypes.Socks5;
s.Connect("www.mentalis.org", 80);
HttpWebRequest reqTest = (HttpWebRequest)WebRequest.Create("http://www.mentalis.org");
So i create a socket manually and then connect it tor, then to the target. But now, i need to send a request to mentalis. But i can't find any way to set a socket to HttpWebRequest, is it even possible to suply manually connected socket o HttpWebRequest ? Or maybe a NetworkStream
Snapd has documentation on a REST API.
I'm able to connect to the socket from C# using the following
var snapSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
var snapEndpoint = new UnixEndPoint("/run/snapd.socket");
snapSocket.Connect(snapEndpoint);
var req = Encoding.ASCII.GetBytes("GET /v2/system-info HTTP/1.1");
snapSocket.Send(req, req.Length, 0);
var bytesReceived = new byte[256];
var bytes = 0;
var response = "";
do
{
bytes = snapSocket.Receive(bytesReceived, bytesReceived.Length, 0);
response = response + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
} while (bytes > 0);
Console.WriteLine(response);
But everything halts at snapSocket.Receive - a response is never sent. I suspect that there's something wrong with the message that I'm sending it.
It turns out that it expects a standard HTTP request, which means a Host: line, a Connection: Close line, and two \ns at the very end are required.
The documentation's following claim...
While it is expected to allow clients to connect using HTTPS over a TCP socket, at this point only a UNIX socket is supported.
... is meant only to imply that HTTPS and TCP do not work yet - HTTP is currently the valid request format even when using the UNIX Socket.
I am not fluent in C# at all, but maybe this python snippet can help lead into a solution:
import requests_unixsocket
session = requests_unixsocket.Session()
r = session.get('http+unix://%2Frun%2Fsnapd.socket/v2/snaps')
r.raise_for_status()
r.json()
I am currently writing a client-server application. The client sends a UDP broadcast message out trying to locate a server, the server sends a UDP broadcast message out identifying its location.
When a client receives a message identifying the servers location it attempts to connect to the server using socket.Connect(remoteEndPoint).
The server listens for these TCP requests on a listening socket and accepts the requests using listensocket.accept(). The clients details get stored in array (including their IP and port number)
The client sends a message to the server with information about the username and password the user entered.
The server checks the database for the username and password and depending on the result sends back a TCP message (this is where it breaks) to the client who sent the request to check the U&P using the listening socket. I am trying to use the below code to send the TCP message but it will not work as i get an error.
TCPSocket.SendTo(message, clientsArray[i].theirSocket.RemoteEndPoint);
I'm not sure about what method you are using.
But in C# there are 2 common classes that can use as server : TcpClient & Socket
in TcpClient
...
//Start Server
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
server = new TcpListener(localAddr, port);
server.Start();
//Accept Client
TcpClient client = server.AcceptTcpClient();
NetworkStream stream = client.GetStream();
String data = "Message From Server";
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
//Send to Client
stream.Write(msg, 0, msg.Length);
...
and in Socket using TCP
...
//Start Server
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress hostIP = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0];
IPEndPoint ep = new IPEndPoint(hostIP, port);
listenSocket.Bind(ep);
listenSocket.Listen(backlog);
//Accept Client
Socket handler = listener.Accept();
String data = "Message From Server";
byte[] msg = Encoding.ASCII.GetBytes(data);
//Send to Client
handler.Send(msg);
...
and in Socket using UDP
You shouldn't use this on your server since you are using TCP
...
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], 11000);
Socket s = new Socket(endPoint.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
String data = "Message From Server";
byte[] msg = Encoding.ASCII.GetBytes(data);
//Send to Client by UDP
s.SendTo(msg, endPoint);
...
Normally, when you get a connection from a client, you'll get a TcpClient. That class has a method GetStream(). If you like to send some data to that client, simply write your desired data to that stream.