I am trying to establish a TCP Client-Server connection between my locally connected computers (MacBook-BigSur is the running server while a Windows 10 laptop is acting as a client). For this, I'm using Visual Studio Code to run both applications as follows:
On macOS:
Console.WriteLine("Starting build agent...");
var listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 12345);
Console.WriteLine("Build agent Started ");
listener.Start();
while (true)
{
var fileName = $"s-{DateTime.Now.Ticks}.tar.gz";
using (var client = listener.AcceptTcpClient())
using (var stream = client.GetStream())
using (var output = File.Create(fileName))
{
Console.WriteLine("Client connected. Starting to receive the file...");
// read the file in chunks of 1KB
var buffer = new byte[1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
Console.WriteLine("Client connected. File received successfuly.");
Console.WriteLine(Execute($"tar -xvf '{fileName}'"));
}
}
On Windows:
var client = new TcpClient("192.168.0.109", 12345);
Byte[] data = File.ReadAllBytes(#"D:\shared\file.tar.gz");
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("data sent.");
However, when the Windows client is trying to establish the connection, it fails saying:
System.Net.Internals.SocketExceptionFactory.ExtendedSocketException: 'No connection could be made because the target machine actively refused it. 192.168.0.109:12345'
Note that after running the server I can see Visual Studio is using the port 12345 by checking it using sudo lsof -i :123456 in Terminal. Besides, my Mac device is using the port 192.168.0.109, the firewall is disabled and I can ping it using my Windows command prompt.
127.0.0.1 is localhost which means by definition the server is only reachable on the same host.
If you want the server to listen on all interfaces don't specify IPAddress.Any respectively IPAddress.IPv6Any or use 0.0.0.0.
Related
I have a client server model.
192.168.77.6 is the client (my code). 192.168.77.18 is a server device. I am sending a request to the server for a response. Once I get the response, I am reading the response and trying to send an acknowledgement of 2 bytes (line 479 of wireshark packet). But, before I can send my acknowledgement, I see that an acknowledgement of 0 bytes is being sent from the client (line 429 of wireshark packet), which causes the server device to send a [FIN,ACK] packet (line 475 of wireshark packet), and it doesn't accept the acknowledgement that I am sending (line 479 of wireshark packet).
Below is the screenshot of the wireshark packets obtained:
Wireshark packet screenshot
I have included my code below:
TcpClient tcpclnt;
NetworkStream stream;
tcpclnt = new TcpClient();
tcpclnt.Connect(ip, port);
stream = tcpclnt.GetStream();
if (tcpclnt.Connected)
{
SendMessage(stream, RequestToSend);
Thread.Sleep(2000);
string readData = "";
readData = readBytes1(stream);
}
tcpclnt.Close();
Below is the readBytes1() function:
private static string readBytes1(NetworkStream stream)
{
byte[] resp = new byte[100];
var memoryStream = new MemoryStream();
int bytes;
do
{
bytes = 0;
bytes = stream.Read(resp, 0, resp.Length);
memoryStream.Write(resp, 0, bytes);
}
while (bytes > 0);
GenerateAcknowledgement(stream);
return Encoding.GetEncoding("ISO-8859-1").GetString(memoryStream.ToArray());
}
GenerateAcknowledgement() is the function that sends 2 bytes of data.
You need to obtain the server and protocol.
The server is closing the connection. This will be in the design of the server.
It's possible that you're not doing something in the request to the server which causes it to close immediately.
Without knowing the protocol or having the server code it's not possible to know why the the server is closing the connection.
I'm trying to communicate with a device that has a Serial COM port that goes out (using RS232 Protocol), which I've hooked up to a converter box that converts the connection to Ethernet.
I've successfully connected to the converter box (which has its own IP) and I've successfully communicated with the device by sending it commands over telnet by using PuTTY, to which it has responded with various data that I've been able to parse.
I've established a connection by creating a new TcpClient, and I'm able to send strings to the device, but every time I get a response back, it's always "??\u0003" which I've researched and found that \uhhhh is a Unicode escape protocol. This confuses me because I have used ASCII encoding for everything.
public string TcpConnect(string cmd)
{
var client = new TcpClient();
//cmd = "ping";
Console.WriteLine("Connecting to server");
client.Connect("169.254.20.40", 23); //22 = ssh, 23 = telnet, 80 = http
Console.WriteLine("CONNECTED SUCCESSFULLY");
Stream tcpStream = client.GetStream();
ASCIIEncoding A = new ASCIIEncoding();
byte[] enable = A.GetBytes("enable" + Environment.NewLine);
byte[] connect = A.GetBytes("connect line 1" + Environment.NewLine);
byte[] ba = A.GetBytes(cmd);
Console.WriteLine("Transmitting.....");
tcpStream.Write(enable, 0, enable.Length);
tcpStream.Write(connect, 0, connect.Length);
tcpStream.Write(ba, 0, ba.Length);
byte[] responseBytes = new byte[4096];
int numBytesRead = tcpStream.Read(responseBytes, 0, responseBytes.Length);
var message = A.GetString(responseBytes, 0, numBytesRead);
Console.WriteLine("\nServer Closed.");
return message;
}
If I were to pass in "$TEAA4B9\r\n" as the message, I would expect something along the lines of "$TEA,086,040,031,000,3798" which is nowhere close to what I'm getting (which is ??\u0003)
Nevermind figured it out
Just kidding! Here's what I did: I added a "System.Threading.Thread.Sleep("1000") before the "tcpStream.Read" line at the bottom, and now it outputs the data I need. The device was outputting garbage on the first line (perhaps a handshake, not sure) and that's all that was being read before it was being stored into "message" and returned (not enough time was spent reading before it moved on to the next line of code)
I am writing FTP client with C#. I typed methods to upload file to FTP server and file upload does work. However, after successful data transmission, client gets disconnected from server. Here are steps I do:
1. Get IP and Port from server by using PASV.
2. Create DATA connection with server using IP and port.
3. Convert file to bytes and send through DATA connection.
4. Send STOR through COMMAND connection
My question is why I get disconnected.
public void PrepareUpload() // Get IP and Port from server by using PASV.
{
String answer;
String message = "PASV\r\n";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
this.ns.Write(data, 0, data.Length);
answer = Response(this.ns);
this.dataPort = getPort(answer, 4) * 256 + getPort(answer, 5);
}
public void DataConnect(string server) // Create DATA connection with server using IP and port.
{
int port = this.dataPort;
this.dataConnection = new TcpClient();
IPAddress ipAddress = Dns.GetHostEntry(server).AddressList[0];
this.dataConnection.Connect(ipAddress, port);
this.nds = dataConnection.GetStream();
}
public void DataTransfer(string filename) // Convert file to bytes and send through DATA connection.
{
byte[] data = System.IO.File.ReadAllBytes(filename);
this.filename = Path.GetFileName(filename);
nds.Write(data, 0, data.Length);
}
public void Upload() // Send STOR through COMMAND connection
{
String message = "STOR " + this.filename + "\r\n";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
this.ns.Write(data, 0, data.Length);
}
The order you describe is wrong. In particular you should not start data transfer before issuing the command which specifies what should happen with the transferred data (i.e. STOR). The correct order would be:
Use PASV or PORT command to determine data port and get response to this command. In case of PORT listen on the given IP:port.
Send the STOR command and read the response. It should be a preliminary response (150).
Create the data connection: with PASV connect to the remote host, with PORT wait for an incoming connections.
Transfer the data and close the data connection.
Wait for the final response (226).
So found this little code snippet that would allow you to ping a Minecraft server in PHP, but now i want to do this in C#.
I tried doing this on my own but for some reason its just not working
UdpClient client = new UdpClient();
IPEndPoint ep;
try
{
ep = new IPEndPoint(IPAddress.Parse("-snip-"), -snip-);
client.Connect(ep);
}
catch { Console.WriteLine("Error"); Console.ReadLine(); return; }
byte[] bytes = new byte[1];
bytes[0] = (byte)0xFE;
client.Send(bytes, bytes.Length);
IPEndPoint rep = new IPEndPoint(IPAddress.Any, 0);
byte[] recv = client.Receive(ref rep);
Console.WriteLine(ASCIIEncoding.ASCII.GetString(recv));
Console.ReadLine();
The server seems to just completely ignore the packet. This is the code snippet i found:
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$fp) return false;
//Send 0xFE: Server list ping
fwrite($fp, "\xFE");
//Read as much data as we can (max packet size: 241 bytes)
$d = fread($fp, 256);
//Check we've got a 0xFF Disconnect
if ($d[0] != "\xFF") return false;
Could anyone please point out what mistake i'm making? Thank you!
As described here
The client initiates a TCP connection to the minecraft server on the
standard port. Instead of doing auth and logging in (as detailed in
Protocol Encryption), it sends the two byte sequence FE 01. This is a
0xFE server list ping packet. If the second byte (the 0x01) is
missing, the server waits about 1000ms then replies with the Server ->
Client format used in 1.3 and earlier.
you need to send a TCP request whereas you're sending an UDP packet...
I have created a LAN chat messaging application using C# that connects all clients who run the program to a server on my computer.
I am now trying to convert this application to work with android devices via Xamarin Studio.
When testing this, the device correctly connects to the server as it can send a message ( saying the device has logged in) which is then broadcasted to the other clients.
However, once the application sends this message the program then closes immediately.
Within the desktop version of the chat client I use the code(which is ran on another thread):
NetworkStream serverStream = default(NetworkStream);
private void getMessage()
{
while (this.keepOpen)
{
Console.WriteLine("getMessage");
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
buffSize = clientSocket.ReceiveBufferSize;
try
{
Console.WriteLine("Read stream");
serverStream.Read(inStream, 0, buffSize);
Console.WriteLine ("Final test");
}
catch
{
Console.WriteLine("failed to read stream");
}
string returndata = Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
message();
}
}
This works the first time it is called as the line "Final test" is displayed. However, after this, when the method gets to this stage again (as it is in a never ending loop) I get an error message saying:
'[dalvikvm-heap] Grow heap (frag case) to 13.455MB for 4194308-byte allocation'
'[dalvikvm-heap] Grow heap (frag case) to 21.444MB for 8388612-byte allocation'
And the line "Final test" is not shown thus the line 'serverStream.Read(inStream, 0, buffSize);' is crashing the app. I have tried to use .Flush() and .Close() however none of these work.
The sending portion of my code runs perfectly using 'serverSocket.Write()' as other clients can receive the messages so why would reading data from the server crash the app?
P.S This is my first android app so I wanted to use a language I was more comfortable with than attempting from scratch with java.
Thanks in advance.
Realised that this error was because I was allocating too much memory when trying to send a messag.
Simple changed
byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
buffSize = clientSocket.ReceiveBufferSize;
To
byte[] inStream = new byte[4096];
buffSize = 4096;