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...
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)
So, I am working on a Game that uses a Server. I am trying to add a username & password system, but have run into a issue. When I send the Data from the client to the server, the Server receives it, but I can't think of a system to specify what the data is and where is should be stored.
For example, say I send the Username from my Client to the Server. The Server receives it, but how can I let it know that it's a username, not a password?
If anyone can help, thank you.
Note: If it helps, I am using C# in Visual Studio.
Server Code
int recv; // Holds how much data we are reading
byte[] data = new byte[1024]; // Byte Array of data, used for everything recived and sent to the server
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 904); // Listener for connections
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // Stores connection from client
socket.Bind(endpoint); // Bind incoming connection to socket
Console.WriteLine(" >> Waiting for client...");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 904); // Wait for connection, once recived, sets sender to connected IP
EndPoint tmpRemote = (EndPoint)sender; // Stores client temp
recv = socket.ReceiveFrom(data, ref tmpRemote); // Stores all client info, get data it's sending (And how much data is in it)
Console.WriteLine(" >> Data received from {0}", tmpRemote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv)); // Convert data into string and display it
string welcome = " >> Welcome to AlphaNET!"; // Welcome Message
data = Encoding.ASCII.GetBytes(welcome); // Convert Welcome to sendable bytes
if (socket.Connected) //Checking if socket is still connected, if so, send welcome message
{
socket.Send(data); // Send welcome message
}
while (true) // Our loop to check for data, goes on forever
{
if (!socket.Connected) // Checks to see if client is not connected, if true, write to console and break the loop
{
Console.WriteLine(" >> Data Sent");
}
data = new byte[1024]; // Resets data var
recv = socket.ReceiveFrom(data, ref tmpRemote);
if (recv == 0) // If no info is recived, break loop
{
break;
}
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
Console.ReadLine();
socket.Close();
Client Code
public void sendUsr()
{
String username = usrBox.Text;
byte[] packetData = System.Text.ASCIIEncoding.ASCII.GetBytes(username);
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(IP), port);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // Makes socket to send data
socket.SendTo(packetData, ep); // Sends data to server
}
As rob said, you may want to format your data using data-interchange format, before you send them. I prefer use JSON provided by Newtonsoft.Json libary. You need to have a reference to it.
Client Code
String dataToSend = JsonConvert.SerializeObject(new { username = usrBox.Text, password = pwdBox.Text });
Server Code
recv = socket.ReceiveFrom(data, ref tmpRemote); // Stores all client info, get data it's sending (And how much data is in it)
dynamic receivedData = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(data, 0, recv));
String username = (string)receivedData.username;
String password = (string)receivedData.password;
I've created my own UDP server/client to see how client->server comunication works and i was wondering if i can make the server to read a specific value... For example, i have a login form that sends ID & password to the UDP server. How can i make the UDP server to recognize the packet that contains the id/password ? A friend told me that you can set a "packet header" in C/C++ but not in C#.
Some code examples or ideas would be greate!
My UDP server's code:
Configuration _conf = Configuration.Load("realmConfig.lua");
int realmPort = _conf["AUTH"]["authPort"].GetValue<int>();
string data = "";
UdpClient __AUTH__ = new UdpClient(realmPort);
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine(" S E R V E R IS S T A R T E D ");
Console.WriteLine("* Waiting for Client...");
while (data != "q")
{
byte[] receivedBytes = __AUTH__.Receive(ref remoteIPEndPoint);
data = Encoding.ASCII.GetString(receivedBytes);
Console.WriteLine("Handling client at " + remoteIPEndPoint + " - ");
Console.WriteLine("Message Received " + data.TrimEnd());
__AUTH__.Send(receivedBytes, receivedBytes.Length,remoteIPEndPoint);
Console.WriteLine("Message Echoed to" + remoteIPEndPoint + data);
}
Client:
string data = "";
byte[] sendBytes = new Byte[1024];
byte[] rcvPacket = new Byte[1024];
UdpClient client = new UdpClient();
IPAddress address = IPAddress.Parse(IPAddress.Broadcast.ToString());
client.Connect(address, 15000);
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("Client is Started");
Console.WriteLine("Type your message");
while (data != "q")
{
data = Console.ReadLine();
sendBytes = Encoding.ASCII.GetBytes(DateTime.Now.ToString() + " " + data);
client.Send(sendBytes, sendBytes.GetLength(0));
rcvPacket = client.Receive(ref remoteIPEndPoint);
string rcvData = Encoding.ASCII.GetString(rcvPacket);
Console.WriteLine("Handling client at " + remoteIPEndPoint + " - ");
Console.WriteLine("Message Received: " + rcvPacket.ToString());
}
Console.WriteLine("Close Port Command Sent"); //user feedback
Console.ReadLine();
client.Close(); //close connection
The UDP/IP packet headers are used for network and transport purposes. All of your application information should be in the UDP payload. You can put any bytes you want there, using any structure you want. Think of the payload as a very small file which you are passing from one application to another and structure it the same way you would a file. For example, the first byte might be a number indicating the type of data in the rest of the payload. In this way, you create your own application-level header.
Just as with a file, you need to remember that word alignment, byte packing, and endian may not be same on different machines. You are sending a sequence of raw bytes, and need to pay attention to how higher level structures will be converted and interpreted.
In addition, individual UDP datagrams are very limited in size. On most networks you will have problems with payloads much bigger than about 1400 bytes, and it is safest to keep payloads below about 512 bytes.
As always with UDP, remember that you are responsible for all flow control and error recovery. If a packet is lost for any reason, you will receive no notification: it simply fails to arrive. If you send packets too quickly, they will be lost. If you do not intend to implement your own specialized flow control and error recovery, consider using TCP instead.
I'm trying to learn the basics of networking and I've built an echo server from this tutorial. I checked the server with telnet and it works perfect.
Now when I'm using some of the many client samples on the Internet:
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
It doesn't work very well. If I will comment the stream.Read line, everything works perfect (expect I can't read). I was also trying to accomplish that in a similar way using asynchronous callback method for the read. and then it only works after I terminate the program (the server handles the request)
I suspect that the way I'm reading from the stream cause this block, but I'm too clueless to understand what I'm doing wrong.
The implementation will block until at least one byte of data can be
read, in the event that no data is available.
From MSDN
Your server propably isn't sending you any data.
Edit:
I tested your client and it works perfectly fine. Try it yourself and set the following parameters:
string server = "google.com";
int port = 80;
string message = "GET /\n";
It's definitely your server which has the problem.