C# .Net application which connects to five different data streams. The data streams are all in the same plaintext format, but have information from different areas. The application creates an array of custom objects, which contains sockets. Each socket connects to its IP/port (same IP, different ports) with no problems. However, when I read data off each socket, I'm getting the same data stream, from the first port number (in range, 10085-10089). For instance, I read data off the socket that's connected to 10088, but I get data from 10085.
The IP/port is grabbed from a database, so I deleted all but the record for port 10088, so the array created has only one object; there is only one socket connection, to port 10088. But I'm still getting only data from 10085.
I've viewed the data from each port through putty; the data is definitely different. Any idea why I'm getting the same data no matter what port a socket's connected to?
This is some simpler code that replicates the problem:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace MultipleFeedConnectionsTest
{
class Program
{
static void Main(string[] args)
{
Socket[] sockets;
IPAddress ipAddress;
IPAddress currentIP;
int portNumber = 10085;
ipAddress = IPAddress.Parse("xxx.xxx.xxx.xxx"); // changed the IP
currentIP = IPAddress.Parse("192.168.5.122");
sockets = new Socket[5];
for (int counter = 0; counter < 5; counter++)
{
if (counter != 1)
{
sockets[counter] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sockets[counter].Bind(new IPEndPoint(currentIP, portNumber + counter));
sockets[counter].Connect(new IPEndPoint(ipAddress, portNumber + counter));
}
}
while (true)
{
for (int counter = 0; counter < 5; counter++)
{
if (counter != 1)
{
byte[] receivedData = new byte[255];
NetworkStream stream = new NetworkStream(sockets[counter]);
stream.Read(receivedData, 0, 255);
Console.WriteLine("FEED " + (portNumber + counter));
Console.WriteLine(Encoding.ASCII.GetString(receivedData));
}
}
}
}
}
}
The above code outputs the same data from each socket. Again, when I access these through putty, they are different.
Tried your code and it works just fine.
You should however get rid of the call to sockets[counter].Bind(........) because it has nothing to do with your code - at all!!
Binding is usually done on the listening socket side, not the connecting one.
Anyway, besides that everything looks normal - I've also made sure I'm sending a unique message to each socket..
Related
I have two third party programs running on my PC which communicate with each other via UDP. Program A is simply a user-interface application which connects via UDP and allows the user to send specific hex commands to program B which sends back some acknowledgement in hex. I know that program B receives on port 11001 and sends on port 11000. I am trying to recreate program A myself in C# as a console application to start with. I've written the following code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
network udpNetwork = new network();
Console.WriteLine("Hello World!");
udpNetwork.StartListener();
}
}
class network
{
private const int sendPort = 11001; //Port to transmit to
private const int receivePort = 11000; //Port to receive on
public void StartListener()
{
string IP_Address = Dns.GetHostByName(Environment.MachineName).AddressList[1].ToString();
IPAddress broadcast = IPAddress.Parse(IP_Address); //create IP address
IPEndPoint endpointSend = new IPEndPoint(broadcast, sendPort);
IPEndPoint endpointReceive = new IPEndPoint(broadcast, receivePort);
UdpClient udpServer = new UdpClient(AddressFamily.InterNetwork);
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.Bind(endpointSend);
var packetData = new byte[] { 0x1F, 0x7F, 0x80, 0x1F, 0xFF };
try
{
udpServer.Connect(endpointSend);
udpServer.Send(packetData, packetData.Length);
udpServer.Close();
UdpClient udpReceive = new UdpClient(AddressFamily.InterNetwork);
udpReceive.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpReceive.Client.Bind(endpointReceive);
Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive);
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("This is the message you received " +
returnData.ToString());
} catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
The code runs fine until the line Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive); where it hangs. I read that this function is blocking which means that the program is waiting for data but obviously not receiving any. Program B listening on port 11001 should send back a response after I have sent the packetData but doesn't. I don't have anyway to use program B to confirm that it is getting the data I am sending. How could I confirm that Program B receives my data in the first place, or do I have some other issue with my code?
edit:
I have edited my code to make use of IPV4 rather than IPV6 as per Jdweng's suggestion. (Shown corrected in the code snippet above). Program B is however still not receiving any data which I can confirm by using TCPView. After launchign the program from within Visual Studio 2019 TCPView shows that there were no received packets by Program B.
Thanks in advance for any help.
There is a program, not written by me that sends UDP multicast packets of info on the local LAN. I've looked the source and it appears they are correctly setup to multicast. This program is WSJT-X which if you are a Ham operator you might have heard of.
The UDP packets contain over the air signal decodes so lots of other programs including mine are interested in these packets.
The problem I'm having is that my UDP receive seems to consume the messages so no other software running on the same machine seems to receive them once my test software starts up.
Here is simple receiver:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ReadUDP
{
internal class Program
{
private static void Main(string[] args)
{
// Setup
int port = 2237;
var multicastIP = IPAddress.Parse("225.0.0.1");
// Create endpoints
var remoteEndPoint = new IPEndPoint(multicastIP, port);
var localEndPoint = new IPEndPoint(IPAddress.Any, port);
// Create and configure UdpClient
var udpclient = new UdpClient();
udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpclient.ExclusiveAddressUse = false;
udpclient.Client.MulticastLoopback = true;
udpclient.MulticastLoopback = true;
// Bind, Join
udpclient.Client.Bind(localEndPoint);
udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);
Task.Run(() =>
{
IPEndPoint sender = new IPEndPoint(0, 0);
while (true)
{
var recvBuffer = udpclient.Receive(ref sender);
var recvStr = Encoding.UTF8.GetString(recvBuffer);
Console.WriteLine("--------------------------------------------------------------------------");
Console.WriteLine($"From:{sender} Data:{recvStr}");
Console.WriteLine("--------------------------------------------------------------------------");
}
});
Console.ReadLine();
}
}
}
This simple program receives the data sent by WSJT-X just fine.
If I clone this project to a new directory, build a new copy of the program and run it, the copy never receives any of the broadcast data while the first copy is running. Only the first running copy gets data.
If I shutdown the first copy then the second copy starts to receive the data.
This acts like the first copy is consuming the message and no other clients receive it. I'm trying to prevent that. I just want to in effect, "peek" at the messages and allow other clients to receive them.
I've tried a a bunch of different options and settings, I've looked at many examples but I have not been able to solve this issue.
Any help would be greatly appreciated.
For those of you that don't have WSJT-X, the following simple UDP sender will send UDP packets:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ReadUDP
{
internal class Program
{
private static void Main(string[] args)
{
// Setup
int port = 2237;
var multicastIP = IPAddress.Parse("225.0.0.1");
// Create endpoints
var remoteEndPoint = new IPEndPoint(multicastIP, port);
var localEndPoint = new IPEndPoint(IPAddress.Any, port);
// Create and configure UdpClient
var udpclient = new UdpClient();
udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpclient.ExclusiveAddressUse = false;
udpclient.Client.MulticastLoopback = true;
udpclient.MulticastLoopback = true;
// Bind, Join
udpclient.Client.Bind(localEndPoint);
udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);
Task.Run(() =>
{
int msgnum = 1;
while (true)
{
var msg = $"Sending message {msgnum++}";
Console.WriteLine("--------------------------------------------------------------------------");
Console.WriteLine($"Send: {msg}");
Console.WriteLine("--------------------------------------------------------------------------");
var bytes = Encoding.UTF8.GetBytes(msg);
udpclient.Send(bytes, bytes.Length, remoteEndPoint);
Task.Delay(2000).Wait();
}
});
Console.ReadLine();
}
}
}
I am doing much the same thing but in VB.net.
WSJT-x runs on my "HamPC" and sends the udp packets to my "Programming" PC for decode.
Program skims the callsigns and looks up the stations Country/State via QRZ's XML service and plays a sound when a new state or country shows up on the band I am listening to.
I have yet to run 2 instances of my program on the "ProgrammingPC" but if I run into what you have I would add code so that the first running instance of my program will rebroadcast all of the packets exactly as received to another port for the second instance of my program to receive.
I found this thread looking for information on finding the Band information in the UDP packets transmitted by WJST-x. I've found and decoded the AudioFreq, TimeStamp and Signal Strength fields easily enough, now I'm scouring the data to locate the Band/Frequency which I need. Was easy in the first generation of my program which repeated read the all.txt file every 15 seconds at 01 16 31 and 41 seconds after the minute and determines which records are new (via simple line counting)
I have Googled high and low but cannot find a published structure of wjst-x's UDP packets - mainly offsets of the fields / how to decode them. I found the fields mentioned above by capturing the UDP packets looking at the contents byte by byte and comparing to the all.txt file for records written during the same transmissions.
The Band/Freq field should be the last one I need.
I believe my suggestion and retransmitting the packets intact to another port for the 2nd instance to receive on will work for you.
Program starts up unware if it is the 1st instance or not. It listen's on the primary port -- If data received on primary uses that port for receive and rebroadcasts the data as received to the 2nd port.
If no data was received on the 1st port it would switch and to listen on the 2nd port and not rebroadcast the data.
Perhaps a bandaid of a workaround but should work.
Best of luck! - 73 ne5B
My client isn't able to connect to the irc server I am trying to connect to. I did some research and it says that I need to listen on port 113 and respond back to the server in a certain format. I am not sure exactly how to do this. When I tried doing it before I got an error message. Here is the code before I tried listening. The irc sends the message to my client "No ident response". Do I need to create an entire different all together that will listen respond on port 113 or can I do it in here?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace ConnectIRC
{
class Program
{
static void Main(string[] args)
{
string ip = "asimov.freenode.net";
string nick = " NICK IKESBOT \r\n";
string join = "JOIN #NetChat\r\n";
int port = 6667;
const int recvBufSize = 8162;
byte[] recvbBuf = new byte[recvBufSize];
//stores the nick
byte[] nickBuf = Encoding.ASCII.GetBytes(nick);
//Stores the room join
byte[] joinBuf = Encoding.ASCII.GetBytes(join);
Socket conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
conn.Connect(ip, port);
conn.Send(nickBuf, nickBuf.Length, SocketFlags.None);
conn.Send(joinBuf, joinBuf.Length, SocketFlags.None);
for(;;){
byte[] buffer = new byte[3000];
int rec = conn.Receive(buffer, 0, buffer.Length, 0);
Array.Resize(ref buffer, rec);
Console.WriteLine(Encoding.Default.GetString(buffer));
}
}
}
}
Despite #Saruman's answer above, you don't need to create an ident server to connect to most IRC networks (including freenode). You can completely ignore the error about "No ident response". It's an outdated technology which is no longer secure and only ever worked properly on Unix-based multiuser systems.
Your actual issue appears to be that you never finish registering the connection to the IRC server. The specification states that you need to send both USER and NICK messages:
string ip = "asimov.freenode.net";
string nick = "NICK IKESBOT \r\n";
// format is: USER <username> * * :<realname>
string user = "USER IKESBOT * * :IKESBOT\r\n";
string join = "JOIN #NetChat\r\n";
int port = 6667;
const int recvBufSize = 8162;
byte[] recvbBuf = new byte[recvBufSize];
//stores the nick
byte[] nickBuf = Encoding.ASCII.GetBytes(nick);
byte[] userBuf = Encoding.ASCII.GetBytes(user);
//Stores the room join
byte[] joinBuf = Encoding.ASCII.GetBytes(join);
Socket conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
conn.Connect(ip, port);
conn.Send(nickBuf, nickBuf.Length, SocketFlags.None);
conn.Send(userBuf, userBuf.Length, SocketFlags.None);
conn.Send(joinBuf, joinBuf.Length, SocketFlags.None);
(You've got an extra space before the NICK - this may or may not break things.)
Aside:
You may find it easier to use TcpClient, StreamReader and StreamWriter to access the underlying socket - they wrap it and deal with the buffers for you. You can then read the response line by line directly into a string, and write to the socket by just passing a string. No fiddling around with encoding and buffers.
TcpClient client = new TcpClient("chat.freenode.net", 6667);
StreamReader reader = new StreamReader(client.GetStream());
StreamWriter writer = new StreamWriter(client.GetStream());
string recievedData = reader.ReadLine();
writer.WriteLine("NICK IKESBOT");
writer.Flush();
Yes you will need to create a totally separate port to listen on and respond back to ident requests
More information on ident can be found here
I want to send a file from a C# server to a AS3 Flash Client. My C# server code for sending the file is something like this:
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();
// This part gets the file and send the data in bytearray
byte[] fileData = File.ReadAllBytes("send/mypicture.jpg");
clientSock.Send(fileData);
Now I need a as3 client. I found this: http://flasharp.blogspot.pt/2010/03/socket-serverclient-chat.html and I constructed something like this:
public function Main():void {
...
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
...
}
function onResponse(e:ProgressEvent):void {
var file:File;
var fs:FileStream;
var fileData:ByteArray = new ByteArray();
// Check if socket has data
if(socket.bytesAvailable > 0) {
while(socket.bytesAvailable) {
// read the socket data into the fileData
socket.readBytes(fileData,0,0);
}
}
file = File.documentsDirectory.resolvePath("teste.jpg");
fs = new FileStream();
fs.open(file, FileMode.WRITE);
// Writing the file
fs.writeBytes(fileData);
fs.close();
}
I've managed to send and receive a file, but it only saves up to 50kbs, anything bigger and you just gest a file with that size.
Any thoughts on how to transfer a file with any size?
I managed to solve this and updated this post with a sample.
UPDATED & SOLVED:
I wanted to send files from a C# server to AS3 Clients using sockets in a Local Network. I had some trouble finding out how to do it, but I managed to do so.
Server (C#):
1 - I create a TcpListener that listens for new clients with any IP in that network to the specified port number;
2 - When a new client connects I create a Thread to handle it;
3 - In that Thread I send the data I want to. In this case that data is divided in two parts, the first is a 4 bytearray that contains the size of the file I want to send, and the second is a bytearray of the file itself;
4 - After the data is sent I close that client connection;
Client (AS3):
1 - First of all I convert my bytearrays to LITTLE_ENDIAN, since AIR is by default BIG_ENDIAN and the data I get from the server is LITTLE_ENDIAN;
2 - Add the events to the socket connection and conect to the server;
3 - On the onResponse function I receive the socket packages to a bytearray;
4 - Save that bytearray into a file;
The last part on the client was the trickiest one, because it took me some time to figure out that AIR is BIG_ENDIAN by default, and how to read the packages.
So basically, what I do is, on the first package that comes in I read the first 4 bytes to a bytearray and then convert that to an int, which gives me my total file size. I use this to know when there are no more packages to receive and therefore finish the connection and save the file. The rest of the first package and subsequent packages are added to a bytearray that will store that file data itself. The workaround here is to start writing on the beggining the first time a package is received and then add the subsequent packages where the last one left off, i.e., first time I write from the 0 to 65321, second one I'll have to write from the 65321 to XXXX, and so on.
The file is being saved to the MyDocuments folder.
I'm unsure if this is the best method to do this, since I'm rather new to socket connection, however this works for me and I tested with files up to 165MB and it works. It supports multiple client connections and is pretty basic, but this is a starting point, not a finish line.
I hope this can help others as it helped me, since I did not find anything like it on the web (regarding file transfer not C# -> AS3 connection).
If someone wants to input some info or needs clarification on something, please feel free to ask.
Last but no least, sample can be downloaded here: http://sdrv.ms/W5mSs9 (Server in C# Express 2010 and Client in Flash Builder 4.6 with Flex SDK 4.6.0)
In case the sample in the link above ever dies out here is the
ActionScript 3 Source Code:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.Socket;
import flash.system.Security;
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.text.TextField;
public class FileTransferLocal extends Sprite
{
private var socket:Socket = new Socket();
private var file:File;
private var fs:FileStream = new FileStream();
private var fileData:ByteArray = new ByteArray();
private var fileSize:ByteArray = new ByteArray();
private var fileDataPosition:int = new int();
private var fileDataFlag:int = new int();
private var fileSizeFlag:int = new int();
private var fileSizeCounter:int = new int();
private var fileDataPreviousPosition:int = new int();
private var myText:TextField = new TextField();
public function FileTransferLocal()
{
try {Security.allowDomain("*");}catch (e) { };
// Convert bytearray to Little Endian
fileSize.endian = Endian.LITTLE_ENDIAN;
fileData.endian = Endian.LITTLE_ENDIAN;
socket.endian = Endian.LITTLE_ENDIAN;
fileSizeFlag = 0;
fileDataFlag = 0;
myText.width = 150;
myText.height = 150;
myText.x = 200;
myText.y = 200;
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);
// Put the IP and port of the server
socket.connect("10.1.1.211", 5656);
}
private function onConnect(e:Event):void {
trace("onConnect\n");
}
private function onClose(e:Event):void {
trace("onClose");
socket.close();
}
private function onError(e:IOErrorEvent):void {
trace("IO Error: "+e);
}
private function onSecError(e:SecurityErrorEvent):void {
trace("Security Error: "+e);
}
private function onResponse(e:ProgressEvent):void {
if(!fileSizeFlag) {
socket.readBytes(fileSize, 0, 4);
fileSize.position = 0;
fileSizeFlag = 1;
fileSizeCounter = fileSize.readInt();
trace("fileSizeCounter -> " + fileSizeCounter);
}
trace("---- New package ----> " + socket.bytesAvailable);
if(fileSizeCounter > 0) {
fileSizeCounter -= socket.bytesAvailable;
if(fileDataPosition != 0) {
fileDataPreviousPosition += fileDataPosition;
}
if(fileData.length == 0) {
fileDataPreviousPosition = socket.bytesAvailable;
socket.readBytes(fileData, 0, socket.bytesAvailable);
} else {
fileDataPosition = socket.bytesAvailable;
socket.readBytes(fileData, fileDataPreviousPosition, socket.bytesAvailable);
}
}
// Saves the file
if(fileSizeCounter == 0) {
trace("File total size" + fileData.length);
file = File.documentsDirectory.resolvePath("test.mp3");
fs.open(file, FileMode.WRITE);
fs.writeBytes(fileData);
fs.close();
myText.text = "File successefully\nreceived!";
addChild(myText);
}
// Is still receiving packages
else {
myText.text = "Receiving file...";
addChild(myText);
}
}
}
}
In C# create a new Windows Application
add a
ListBox call it statusList
Label call it port
Label call it status
C# Source code in Sample Above:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Reflection;
namespace ServerThread
{
public partial class ServerThread : Form
{
private TcpListener tcpListener;
private Thread listenThread;
public ServerThread()
{
InitializeComponent();
// Port number
int portNumber = 5656;
port.Text = portNumber.ToString();
// Create a TcpListener to cover all existent IP addresses with that port
this.tcpListener = new TcpListener(IPAddress.Any, portNumber);
// Create a Thread to listen to clients
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
// Blocks until a client has conected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
// Create a Thread to handle the conected client communication
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
// Receive data
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
while (true)
{
try
{
// Sending data
string filePath = "send/mysong.mp3"; // Your File Path;
byte[] fileData = File.ReadAllBytes(filePath); // The size of your file
byte[] fileSize = BitConverter.GetBytes(fileData.Length); // The size of yout file converted to a 4 byte array
byte[] clientData = new byte[fileSize.Length + fileData.Length]; // The total byte size of the data to be sent
fileSize.CopyTo(clientData, 0); // Copy to the file size byte array to the sending array (clientData) beginning the in the 0 index
fileData.CopyTo(clientData, 4); // Copy to the file data byte array to the sending array (clientData) beginning the in the 4 index
// Send the data to the client
clientStream.Write(clientData, 0, clientData.Length);
clientStream.Flush();
// Debug for the ListBox
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate {
statusList.Items.Add("Client IP: " + tcpClient.Client.RemoteEndPoint.ToString());
statusList.Items.Add("Client Data size: " + clientData.Length);
}));
}
}
catch
{
//
break;
}
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate
{
statusList.Items.Add("File successefully sent!");
}));
}
// Close the client
tcpClient.Close();
}
}
}
}
I am trying to make a Minecraft fake client a.k.a Minecraft chatbot in c# using packets.
I already tried lots of different ways to acomplish this but no luck.
Everytime I send a packet it sends no data (Using a packetsniffer).
Although the packetsniffers says that the total size of the packet is: 190 bytes.
and the size is: 17 bytes.
Here is my code:
static TcpClient client = new TcpClient();
static void Main(string[] args)
{
Console.WriteLine("Start GATHERING INFO.....");
Console.Write("Write a ip: ");
IPAddress ip = IPAddress.Parse("192.168.178.11");
try
{
ip = IPAddress.Parse(Console.ReadLine());
}
catch
{
Console.Write("\nUnknown/Wrong ip entered redirecting to : 127.0.0.1 (AKA Localhost)");
ip = IPAddress.Parse("192.168.178.11");
}
Console.Write("\nWrite a port: ");
int port = int.Parse(Console.ReadLine());
Console.WriteLine("Connecting.....");
try
{
client.Connect(ip, port);
client.NoDelay = false;
Console.WriteLine("Connection succesfull!");
}catch
{
Console.WriteLine("--== ERROR WHILE TRYING TO CONNECT PLEASE RESTART PROGRAM ==--");
Console.ReadKey();
client.Close();
Main(args);
}
Stream stream = client.GetStream();
Console.Write("Please enter a username: ");
string usrn = Console.ReadLine();
Console.Write("\n");
byte[] data = new byte[3 + usrn.Length*2];
data[0] = (byte)2;
data[1] = (byte)29;
gb(usrn).CopyTo(data, 2);
stream.Write(data, 0, data.Length);
Console.ReadKey();
}
public static byte[] gb(String str)
{
return System.Text.ASCIIEncoding.ASCII.GetBytes(str);
}
Here is how the packet should look like:
http://www.wiki.vg/Protocol#Handshake_.280x02.29
I'm ignoring server host and server port since the other bots didnt use it. (although they didnt work to :/
Here's what the original client packet holds:
'shows weird goto: https://dl.dropbox.com/u/32828727/packetsocketsminecraft.txt '
timboiscool9 (my username)
192.168.178.1 (server ip)
There's more after that but this is what i need.
I am fairly new to sockets and tcpclients
I cleaned up your code a bit:
static void Main(string[] args)
{
bool keepTrying = true;
while (keepTrying)
{
Console.Write("Enter server IP Address: ");
IPAddress ip;
if(!IPAddress.TryParse(Console.ReadLine(), out ip))
{
Console.WriteLine("Invalid ip entered, defaulting to 192.168.178.11");
ip = IPAddress.Parse("192.168.178.11");
}
Console.Write("Enter server port: ");
Int16 port;
if(!Int16.TryParse(Console.ReadLine(), out port))
{
Console.WriteLine("Invalid port entered, defaulting to 1234");
port = 1234;
}
Console.WriteLine("Connecting.....");
try
{
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(ip, port));
client.NoDelay = false;
Console.WriteLine("Connection succesfull!");
List<byte> data = new List<byte>() { 2, 29 };
Console.Write("Please enter a username: ");
byte[] userName = ASCIIEncoding.ASCII.GetBytes(Console.ReadLine());
data.AddRange(userName);
using (var stream = client.GetStream())
{
stream.Write(data.ToArray(), 0, data.Count);
Console.Write("Data sent!");
}
keepTrying = false;
}
catch
{
Console.WriteLine("--== ERROR CONNECTING ==--");
Console.WriteLine();
}
}
}
As for your original question, we need more information. You say that the packet sniffer shows no data but then you say the data has a size. So are you seeing data or not? Are you sure the server is up? The code I posted works for me, meaning it connects to a server on my local system and sends the bytes.
This is a bit old, but I'll still see if I can help you out.
The Minecraft protocol is quite complicated, and you will not be able to connect to Minecraft servers without implementing the vast majority of it. The protocol details can be found here.
I suggest you consider going a different route. Because of how complex Minecraft is, I'd avoid implementing it yourself. Luckily, I'm a Minecraft enthusiast, and I've done most of the work for you. I suggest you take a look at the Craft.Net library. It contains a full protocol implementation and making a chat bot from it would be trivial. In fact, here's an example chat program using Craft.Net for you to peruse.