I need to make my PC reply to a windows application which is sending [SYN] packet constantly and expecting [SYN, ACK] from my PC. My goal is to record messages received from that application using wireshark. For that I need to write an application which can send reply to that PC. I am not experienced in TCP protocol, so need suggestions how can I send [SYN, ACK] reply with some C# code?
Wireshark Capture
namespace TCP_CLIENT
{
class Program
{
const int PORT_NO = 5000;
const string SERVER_IP = "192.168.1.100";
static void Main(string[] args)
{
//---listen at the specified IP and port no.---
IPAddress localAdd = IPAddress.Parse(SERVER_IP);
TcpListener listener = new TcpListener(localAdd, PORT_NO);
Console.WriteLine("Listening...");
listener.Start();
}
}
}
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?
I have a service, which connects to the Socket Server (both are C#). The Service connects and successfully sends data to the Socket Server, but "freeze" on socket.Receive(receivedBytes); - line. This is happening when they are on different servers. When both (the Service and the Socket Server) are on the same machine - it works. In the Socket Server I opened the TCP port, inbound and outbound, on the service's server I opened the TCP port, inbound only. This is the code on the service side:
byte[] receivedBytes = new byte[1024];
IPHostEntry ipHost = Dns.GetHostEntry(socketHost);
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, socketPort);
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sender.Connect(ipEndPoint);
byte[] forwardMessage = Encoding.ASCII.GetBytes(msg);
sender.Send(forwardMessage);
int totalBytesReceived = sender.Receive(receivedBytes);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
What I miss? Should I do any other security configurations?
Thank you!
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.
I am trying to write a simplest multithreaded TCP server in C#, which receives the data from multiple clients.
Every time a new client is connected, the socket connection is established and the socket is passed as an argument to the new class function, after that the while loop runs and receives the data till the client is connected.
The problem here is that the "socket.receive" is not blocking and receives 0 bytes of data. So the loop runs continuously, without blocking at socket.receive ("clientSocket.Receive(bb)" in the code.).
I am using Chrome browser as a client for testing.
Even if I use any other client, the behavior of the TCP server remains the same.
The client sends the data only once but server continuously receives 0 bytes and while loop keeps on running.
I am pasting the Server output for reference.
Please help in blocking the Server at socket.receive to wait for next client transmission.
The strange thing is that even if 0 bytes are received, the exception is also not called.
Please help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
Threading;
using System.Timers;
using System.Security;
using System.Security.Permissions;
namespace SERVER
{
static class Constants
{
public const int port = 8080;
public const int buffer_size = 512;
}
class Program
{
static public string LocalIPAddress()
{
IPHostEntry host;
string localIP = "";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
break;
}
}
return localIP;
//return ip;
}
static void Main(string[] args)
{
//IPEndPoint ipObj = new IPEndPoint(IPAddress.Parse("Server IP goes here"), 20487); //20487 is port. you can change it according to your wish
System.Net.IPAddress IP = IPAddress.Any;
int port = Constants.port;
TcpListener listnerObj = new TcpListener(IP, port);
listnerObj.Start();
string client_addr;
string[] client_addr_split;
string IP_string = LocalIPAddress();
Console.WriteLine("Server Started on {0}:{1}", IP_string, port);
while (true)
{
Console.WriteLine("================================");
Console.WriteLine("** Waiting For Client **");
Socket clientSocket = listnerObj.AcceptSocket(); // waiting for the client to connect
client_addr = clientSocket.RemoteEndPoint.ToString();
client_addr_split = client_addr.Split(':');
client_addr = client_addr_split[0];
Console.WriteLine("Client Connected {0}", client_addr);
ParameterizedThreadStart thread = delegate { new communication().doCommunicate(clientSocket, client_addr); };
Thread th = new Thread(thread);
th.Start(); // start the thread here
}
}
class communication
{
public int byteReceived;
public byte[] bb;
public void doCommunicate(Socket clientSocket, string client_addr)
{
clientSocket.Blocking = true;
bb = new byte[Constants.buffer_size];
//Console.WriteLine("***** Entered DoCommunicate *****");
while (clientSocket.Connected)
{
//Console.WriteLine("Entered While");
try
{
//Console.WriteLine("Entered TRY");
Console.WriteLine("Waiting to recieve Data from IP : client_addr");
//int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
byteReceived = clientSocket.Receive(bb, 0, bb.Length, SocketFlags.None);
//byteReceived = clientSocket.Receive(bb);
}
catch (SocketException e)
{
Console.WriteLine("Error: Socket Exception.\n{0}\n{1}.", e.Message, e.ErrorCode);
break;
}
catch (ArgumentNullException e)
{
Console.WriteLine("Error : Argument Null Exception.\n{0}", e.Message);
break;
}
catch (ObjectDisposedException e)
{
Console.WriteLine("Error : Socket Disposed Exception Caught.\n{0}", e.Message);
break;
}
catch (SecurityException e)
{
Console.WriteLine("Error: Security Exception.\n{0}", e.Message);
break;
}
//clientSocketglobal.Send(Encoding.Default.GetBytes("Hello Client"), SocketFlags.None);
Console.WriteLineWriteLine("Received Byte count : {0}, from IP : {1}", byteReceived, client_addr); // Do whatever you want to do with the data recieved. Parsing and storing etc.
Console.WriteLine(Encoding.UTF8.GetString(bb));
}
//Console.WriteLine("While Loop Exited");
Console.WriteLine("Socked and Class Object Disposed");
clientSocket.Close();
clientSocket.Dispose();
GC.Collect();
}
}
}
}
OUTPUT Of server :
Server Started on 10.0.0.2:8080
================================
** Waiting For Client **
Client Connected 10.0.0.2
================================
** Waiting For Client **
Client Connected 10.0.0.2
================================
** Waiting For Client **
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 386, from IP : 10.0.0.2
GET /HelloWorld HTTP/1.1
Host: 10.0.0.2:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Waiting to recieve Data from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
Received Byte count : 0, from IP : 10.0.0.2
If you received 0 bytes, that usually means the sender has closed their send socket. In a Socket, the send and receive channels are separate; I expect what is happening is that your send (their receive) is still open and available, hence clientSocket.Connected returning true (you can still send them a reply), but: they closed their send (your receive) as soon as they sent their payload (this is common, to indicate the end of a batch). Basically, you just need to detect the 0-byte receive, and treat that as the end: no more data will ever be incoming once you have had a non-positive reply from receive. So just write any response you need to write (they can still be listening, even though they will never speak again), and shutdown the socket.
As a side note: in HTTP/1.1 with Connection: keep-alive, the can keep their socket open ready to send the next request - but it just looks like in this case, they simply didn't. They closed their socket immediately after issuing the request. Which is fine. Just serve the response and close the socket completely. No more requests will be incoming.
I have a socket server (written on C++) which receives requests from clients and sends responses back. So, my test client application (C#) is very simple:
try {
UdpClient udpClient = new UdpClient(10241);
// Connect
udpClient.Connect(server_ip_address, 10240);
// prepare the packet to send
iWritableBuff wbuff = new iWritableBuff();
[ ... ]
// Send
udpClient.Send(wbuff.GetBuff(), (int)wbuff.Written());
// Receive a response
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
Console.WriteLine("We've got some data from the server!!! " + receiveBytes.Length + " bytes.");
udpClient.Close();
} catch (Exception e) {
Console.WriteLine("ERROR: " + e.ToString());
}
I run both applications on the same computer. Server receives a request to port 10240 from the client port 10241 and sends a response back to client port 10241, but client never receive it. So, I'm sure that server sends packet back, because everything works perfectly with C++ client. It means that I'm, doing something wrong on my C# client. Any idea?
Thanks!
P.S.> Just test it with Berkley Socket C# client:
try {
// Create socket
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Bind
IPEndPoint myEP = new IPEndPoint(IPAddress.Any, 0);
s.Bind(myEP);
// prepare the packet to send
iWritableBuff wbuff = new iWritableBuff();
[ ... ]
// Send it
IPEndPoint sEP = new IPEndPoint(IPAddress.Parse(server_ip_address), 10240);
int res = s.SendTo(wbuff.GetBuff(), (int)wbuff.Written(), 0, sEP);
// Receive the response
byte[] receiveBytes = new Byte[1024];
EndPoint recEP = new IPEndPoint(IPAddress.Any, 0);
res = s.ReceiveFrom(receiveBytes, ref recEP);
Console.WriteLine("We've got some data from the server!!! " + res + " bytes.");
} catch (Exception e) {
Console.WriteLine("ERROR: " + e.ToString());
}
And it works perfect! What's is wrong with UdpSocket?
Not sure if this applies to UDPClients that don't broadcast packets but simply send one to a specified address, but I ran into a similar roadblock.
I had a UDPClient that broadcasted a udp packet for discovery of some custom machines on our network. When I tried to receive the message that the servers would simply echo back, it would not receive the information and would timeout. Turns out that if you use a UDPClient that broadcasts a message out, it WILL NOT be able to receive messages back. It's not documented anywhere, except for one forum topic on msdn that I luckily came across.
The solution was to send the message, immediately close the socket, open a NEW UDPClient on the same port, then use this new UDPClient to receive the echoed back UDP packet. Very annoying.
Give that a shot and see if it works. It definitely works for sending out a broadcasted packet.