I have found the below code on the internet, and I need to allow my users to enter their own IP Address and Port number, as opposed to hard-coded.
I allow my users to enter a IP and Port from two individual text boxes.
try
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting");
tcpclnt.Connect(syn_ip.Text, 7878);
Console.WriteLine("Connected");
//String str=Console.ReadLine();x
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes("data here");
Console.WriteLine("Transmitting.");
stm.Write(ba, 0, ba.Length);
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
for (int i = 0; i < k; i++)
Console.Write(Convert.ToChar(bb[i]));
tcpclnt.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error:" + ex.ToString());
}
It will let me send my data over using the above, but I really do need to be able to enter in the port number.
When I do try something like the below, I get the following error: Argument: Cannot convert from 'string' to 'int'.
tcpclnt.Connect(syn_ip.Text, syn_port.Text);
Thanks for all the help in advance :)
James.
In this code
tcpclnt.Connect(syn_ip.Text, syn_port.Text);
syn_port.Text is a string type, but an integer is expected. The simple fix is
tcpclnt.Connect(syn_ip.Text, int.Parse(syn_port.Text));
This will throw an exception at runtime if anything but an integer is entered. Instead, consider the more robust solution
int port;
bool ok = int.TryParse(syn_port.Text, out port);
if (ok)
{
tcpclnt.Connect(syn_ip.Text, port);
}
else // Some error message
Note that you should also modify the UI to only allow integers to be entered. You should also never trust a UI (as a general practice), so also validate that you received an integer in your code that uses the input.
You need to convert the port to an integer value.
int port = Int32.Parse(syn_port.Text);
tcpclnt.Connect(syn_ip.Text, port);
tcpclnt.Connect(syn_ip.Text, int.Parse(syn_port.Text));
You just need to convert the port string to an int, as the error suggests.
Since you're trying to convert user input I would recommend int.TryParse considering it could not always be an int.
int port;
if (int.TryParse(syn_port.Text, port))
{
tcpclnt.Connect(syn_ip.Text, port);
}
Related
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 am deveoping an application that communicates with a thermal printer by using ESC/POS commands.
According to documentation, when sending DLE EOT n command, printer should respond with the status, but it sends nothing and of course, application get stuck waiting for the reply.
This is the basic code in C#:
try
{
int bytesSent = _socket.Send(new byte[] { EscPos.DLE, EscPos.EOT, 2 }); // Transmit Printer Status
byte[] bytes = new byte[1024];
int bytesReceived = _socket.Receive(bytes);
if (bytesSent == 3 && bytesReceived > 0)
return !IsBitSet(bytes[0], 6);
}
catch (Exception ex)
{
OnError(ex);
}
Any help will be appreciated, thanks
Jaime
Ehem.. I have found the problem.... I realized of it after the comment I sent here.... the EscPos.DLE constant was bad defined.
Thanks anyway
Jaime
I am writing a program which goal is to communicate with the weight terminal using TCP client.
I'm sending specified messages (eg. checking status) and depending on the replies I'm making some another process.
First, some code.
Connection:
public static void PolaczZWaga(string IP, int port)
{
IP = IP.Replace(" ", "");
KlientTCP = new TcpClient();
KlientTCP.Connect(IPAddress.Parse(IP), port);
}
Sending message (eg. checking status)
public static string OdczytDanychZWagi(byte[] WysylaneZapytanie)
{
// Wysyłka komunikatu do podłączonego serwera TCP
byte[] GotoweZapytanie = KomunikatyWspolne.PoczatekKomunikacji.Concat(WysylaneZapytanie).Concat(KomunikatyWspolne.KoniecKumunikacji).ToArray();
NetworkStream stream = KlientTCP.GetStream();
stream.Write(GotoweZapytanie, 0, GotoweZapytanie.Length);
// Otrzymanie odpowiedzi
// Buffor na odpowiedz
byte[] odpowiedz = new Byte[256];
// String do przechowywania odpowiedzi w ASCII
String responseData = String.Empty;
// Odczyt danych z serwera
Int32 bytes = stream.Read(odpowiedz, 0, odpowiedz.Length);
responseData = System.Text.Encoding.ASCII.GetString(odpowiedz, 0, bytes);
return responseData;
}
After Form1 open I make an connection and checking status
string odp = KomunikacjaSieciowa.OdczytDanychZWagi(OdczytZWagi.Kom_RejestrStatusu);
char status = odp[0];
switch(status)
{
case 'B':
KomunikacjaSieciowa.WysylkaDoWyswietlaczaWagi_4linie(WysylkaDoWyswietlacza_Komunikaty.LogWitaj, WysylkaDoWyswietlacza_Komunikaty.LogZaloguj, WysylkaDoWyswietlacza_Komunikaty.PustaLinia, WysylkaDoWyswietlacza_Komunikaty.LogNrOperatora);
string NrOperatora = KomunikacjaSieciowa.OdczytDanychZWagi(OdczytZWagi.Kom_ZatwierdzoneF1);
//int NrOperatora_int = Convert.ToInt32(NrOperatora);
break;
// here goes next case etc
Here starts my problem - communication takes place only once and the operation requires data on the terminal. Before the operator enters data program ends.
How to change the code / loop / add a timer to repeated communication to achieve a certain status?
More specifically, as in this passage:
case 'B':
KomunikacjaSieciowa.WysylkaDoWyswietlaczaWagi_4linie(WysylkaDoWyswietlacza_Komunikaty.LogWitaj, WysylkaDoWyswietlacza_Komunikaty.LogZaloguj, WysylkaDoWyswietlacza_Komunikaty.PustaLinia, WysylkaDoWyswietlacza_Komunikaty.LogNrOperatora);
string NrOperatora = KomunikacjaSieciowa.OdczytDanychZWagi(OdczytZWagi.Kom_ZatwierdzoneF1);
repeat "string NrOperatora" depending on the returned data?
Where's the best place to make loop?? Maybe I should use thread??
I think using stream.BeginRead and checking the status when reads are complete is the best way so if the status is not OK you can call stream.BeginRead to the same method so it will be a loop calling here self until status is OK
I am trying to send a word over to an Arduino running as a server, from a WPF C# application. Every now and again the complete work is not sent.
C# Code
public void send(String message)
{
TcpClient tcpclnt = new TcpClient();
ConState.Content = "Connecting.....";
try
{
tcpclnt.Connect("192.168.0.177", 23);
ConState.Content = "Connected";
String str = message;
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
stm.Write(ba, 0, ba.Length);
tcpclnt.Close();
}
catch (Exception)
{
ConState.Content = "Not Connected";
return;
}
}
How it is sent to the method:
String mes = "back;";
send(mes);
Arduino code:
if (client.available() > 0) {
// Read the bytes incoming from the client:
char thisChar = client.read();
if (thisChar == ';')
{
//Add a space
Serial.println("");
}
else {
//Print because it's not a space
Serial.write(thisChar);
}
}
The Arduino is using the chat server example. I am sending "back;" and "forward;" across. The results on the serial monitor:
back
forwaback
forward
back
forwaforwar
The problem seems to be with this code:
if (client.available() > 0) {
// read the bytes incoming from the client:
char thisChar = client.read();
...
}
What it does is:
Check if we have received data from the client
Read a single byte from the client buffer
Exit, and go on to do other things
As the OP pointed out, this comes direct from Arduino chat server example. In that example, this working correctly in loop() depends on the alreadyConnected flag being set right after a new connection is made: if it isn't, then the buffer is flushed before any data is read. That's one possible landmine.
Nonetheless, there is no reason to change the if block to be a while loop in the OP's case so, in other words instead of
if (client.available() > 0) {
have
while (client.available() > 0) {
The only reason to have an if statement there is to make sure that you frequently do other processing in loop() if you have clients that send a lot of data: If the reading of client data is done from inside a while this loop will not exit until the there is no more data from the client. Since this doesn't seem to be an issue in the asked-about case, the if to while change makes sense.
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.