I'm still learning C#, so don't yell at me for not doing anything right. Also, i know I should probably be using WPF, but in my current condition I need to use winForms.
Client:
public void sendData(String dataIn)
{
String IP = textBox1.Text;
String Port = textBox2.Text;
net.Send(dataIn, IP, Port);
}
Server:
public string listenForData()
{
String dataOut = net.Listen();
return dataOut;
}
How do I create a method that takes a string and sends it to a server application. I know it has something to do with TCP sockets. I've looked but I don't understand any tutorials or videos i've found.
Thanks in advance, Noah.
You could try looking into the TCP Client Class.
https://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.110).aspx
You can get the stream from tcp client and use that to write your string to, by converting the string to a byte[] first.
// Setup TCP Client with valid values first. Make Client and stream private or public variables/properties.
TCPClient client = new TCPClient(IP, (int)Port); // Following validation on Port & IP
NetworkStream stream = client.GetStream();
private void SendDataToServer(String dataIn) {
Byte[] StringToSend = Encoding.UTF8.GetBytes(dataIn);
stream.Write(StringToSend, 0, StringToSend.Length);
}
Related
So in my client I am looking for a way to return how many times a background worker was run to a server. Here is the code section for the client:
}
public int searchcount = 1;
public void SL_Click(object sender, EventArgs e)
{
try
{
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(RecieveIP.Text, 8001); // use the ipaddress as in the server program
MessageBox.Show("Connected");
Stream stm = tcpclnt.GetStream();
MessageBox.Show("Listening for information......");
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
string atk = Encoding.UTF8.GetString(bb.AsSpan(0, k));
Console.WriteLine($"S Connected to attack server at IPv4 address {RecieveIP.Text} Attack command Received: {atk}. If command is g, attacking google. Y means attacking yahoo. A means attacking aol. Yo meants attacking youtube, and s is attacking spotify");//test
//if you want your check
//this will not work if your incoming data contains white space or other bytes that were converted.
if (atk == "g" || atk.Contains("g"))
MessageBox.Show("Recieved Command " + atk);
if (atk == "g")
{
MessageBox.Show("Google");
search.RunWorkerAsync();
On thought, I do have a string
public int searchcount = 1;
Which the background worker in question adds one to display to the person running the client how many times it was run.
Console.WriteLine("Since start: " + count++.ToString());
Is there a way to return the count++ string to the server via both TCP and UDP? Thanks.
TCP(socket) is a protocol that you can send packages both ways. Udp on the other hand is stateless, you can only send packages from client to server. You cant maintain UDP connections open and keep sending/receiving packages. That said, you can send packages from client to server using UDP if the server dont need to respond your package.
I'm really doing some resume on what tcp/udp protocols are and i really encourage you to read about them on MS official docs before using anything on production.
Here some TCP , UDP and sockets examples and documentation on MS official docs.
Tcp Client/Server
Udp Client/Server
Sockets
Since days I'm trying to get (JS)wss/(c#)SslStream connection to work in order to create a wss server in mono c#.
My Problem : When an incomming secure WebSocket connection is accepted by the server, I can't get data from it in order to begin the handshake process.
What I did so far :
I setup a TCPListener that accept the client giving me a TCPClient instance.
I get the stream from the TCPClient and create a SslStream from it.
I synchronously authenticate it with AuthenticateAsServer(X509Certificate2)
I unsuccessfully try to read data
Other details :
I note that if I use a Stream object instead of an SslStream one, I succed in getting data from it (but crypted as expected)
I tested to connect my WebSoket to same adress/port to Fleck (built on my box with Monodevelop too) using the same pfx certificate and got it working properly
I note also that Fleck throw messages saying it recieve 0 byte, then it close the connection and (in some way) reconnect it and get data properly from Socket/SslStream.
I don't get any error, SslStream seem to be correctly authenticated
I correctly connect clients in https and deal with requests on an another port in the same program
My Configuration :
OS : ArchLinux
C# : Mono .Net Framework 4.7
Browsers (Chromium & Firefox)
Despite of all my research so far I've not found the solution , maybe someone can help me to wonder what I miss here ...
Thanks in advance for any help !
The listen code :
public void AudioListen ()
{
audioComListener.Start ();
while (isAudioActive) {
TcpClient s = audioComListener.AcceptTcpClient ();
Stream clientStream;
string hellostr;
clientStream = getClientStream(s);
if(debugCommuncation)
{
logToFileLine("(KEY) HandShaking begins with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
if(!WebSocketHandshake(clientStream))
{
if(debugCommuncation)
{
logToFileLine("(KEY) (X) HandShake read 0 byte from "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
s.Close();
return;
}
else
{
logToFileLine("(KEY) HandShaking OK with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
hellostr=streamReadLine(clientStream);
if(hellostr.IndexOf("hello:")==0)
{
string usrstr=hellostr.Split(':')[1];
User usr= Users.GetUser(usrstr);
if(usr!=null)
{
usr.TcpC=s;
User usrdest=usr.corresp;
if( usrdest!=null &&
usrdest.ByPass==null &&
usrdest.TcpC!=null)
{
Stream clientStream2 = getClientStream(usrdest.TcpC);
usr.ByPass=new TCPByPass(clientStream,clientStream2);
usrdest.ByPass=usr.ByPass;
}
}
}
Thread.Sleep (1);
};
}
Function to get the SslStream :
private Stream getClientStream(TcpClient s,bool forceHTTP=false)
{
Stream clientStream;
if(isSSL && !forceHTTP)
{
clientStream = new SslStream (s.GetStream ());
((SslStream)clientStream).AuthenticateAsServer(SrvCert);
// Set timeouts for the read and write to 5 seconds.
/**/clientStream.ReadTimeout = 5000;
clientStream.WriteTimeout = 5000;
//SecuDiag.MakeAllDiag(((SslStream)clientStream));
}
else
{
clientStream=s.GetStream ();
}
return clientStream;
}
Function that try to get data for hanshake purpose :
public bool WebSocketHandshake(Stream clientStream)
{
string hellostr;
// Here I test trying to get data (Also tried to use Stream.ReadByte())
Byte[] toto=new Byte[2048];
((SslStream)clientStream).Read(toto,0,2048);
if(toto[0]==0)return false;
Console.WriteLine("#############################################");
Console.WriteLine("toto array is {0} bytes long",toto.Length);
for(int t =0;t<10;t++)
{
for(int u =0;u<10;u++)
{
Console.Write(toto[t*10+u].ToString());
}
Console.WriteLine(";");
}
Console.WriteLine("#############################################");
// Trying to get data
//hellostr=streamReadLine(clientStream);
//Console.WriteLine(hellostr);
return true;
}
I think I solved the problem. I don't understand why, but I think its necessary to close the accepted connection just after accepting it iaoi the connection is wss. The the websocket wil automagically reconnect :)
I have a solution with two projects which act as Server and Client respectively. The Client is a simple console application which sends data to the server. The server is a WPF application which receives the data and displays it in a datagrid. The MVVM approach is used here.
In the Server UI there are three textboxes in which the user can type in:
IP Address: ("127.0.0.1")
Port: (some port)
Delimeter: (some char like '#' for example)
The challenge for me in this one is that, whatever delimeter the user provides, it should be used in the client project, to be put in between the data which is to be sent. For example the client sends:
Name + Delimeter + Surname + Delimeter + Age
What i have tried:
I added a Utils class with static fields for IPAddress, port and delimeter like this:
public class Utils
{
public static string IP_ADDRESS = " ";
public static int PORT = 0;
public static char DELIMETER = '\0';
}
I then tried to change these values in my ViewModel where the respective properties which are bound to the UI are by assigning them:
private void storeData()
{
Utils.IP_ADDRESS = IP;
Utils.PORT = Port;
Utils.DELIMETER = Delimeter;
}
In the client program:
static void Main(string[] args)
{
Client client = new Client(Utils.IP_ADDRESS, Utils.PORT);
while (true)
{
client.SendData("some Name" + Utils.DELIMETER + "some Surname" + Utils.DELIMETER + some Age + Utils.DELIMETER + "something else");
Thread.Sleep(3000);
}
}
The problem here is that whenever i start a new Client instance the values from the util class are still the default ones (null).
Any help is appreciated.
Let's break down your problem:
The server can change ip or ports at will and the clients will somehow guess the new port and connect.
The server changes the delimiter at will and the clients adapt to the new delimiter.
Problem 1 is impossible. Information cannot magically get transferred to clients before the client connects to the server, and the client needs ip and ports to connect to the server. Whatever technique you use to transfer the ip and port to the client is a better communication channel than your client/server, so you don't need a client/server.
Problem 2 has been solved by WCF already. Use WCF and SOAP or REST (which is just HTML).
Here is a sample of what the code would look like for the clients to determine the delimiter before sending the main request:
class Server
{
private TcpListener _listener = new TcpListener(12312);
public void Start()
{
_listener.Start();
while (true)
{
var client = _listener.AcceptTcpClient();
var stream = client.GetStream();
var request = getRequest(stream);
if (request == "GetDelimiter")
{
SendResponse(Utils.DELIMITER, stream);
}
else
{
ProcessNameSurnameAge(request);
}
}
}
}
class Client
{
private TcpClient _client = new TcpClient();
public void DoTheThing()
{
_client.Connect("127.0.0.1", 12312);
var stream = _client.GetStream();
SendRequest("GetDelimiter", stream);
var delimiter = GetResponse(stream);
var newRequest = "some Name" + delimiter + "some Surname" + delimiter + "some Age" + delimiter + "something else";
SendRequest(newRequest);
}
}
Note that I skip over the encoding details of sending data over TCP because it seems like you've already got a handle on that.
I was able to solve this in a rather simple manner. Steps i used to solve are as follow:
In the server:
Created a text file in my solution.
When the server starts in my view model, i saved the properties ip, port and delimeter in a string array.
Next i used the IO File class to write the content of the array in the text file.
In the client:
First i read from the file.
Next i created the client instance and passed the ip and port as parameters to it's constructor.
Thank you D Stanley and Damian Galletini for your suggestions. Also thank you everybody else who tried to help.
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'm working o a project that monitors the IP and HWID on a specific port by TCPListen sent from a client that kills a specific process.
Monitor works perfect, I receive ip and hwid and manage to save to .txt files but what I want to do is to implement a method in server how to block the ip by reading the hwid from a text file.
If some one can help me please I will appreciate it really.
Here is a part from code of client(send) , server (receive):
Server:
textFromClient = ("From: " + tcpClient.Client.RemoteEndPoint + " HWID:" + encoder.GetString(message, 0, bytesRead));
Client:
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(getUniqueID("C"));
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
I think I understand but maybe that I didn't explain right. Well, my server listen on any ip on port 8000 . Clients connects automaticly to server ip and port: exemple : 127.0.0.1:8000. Well clients works like this: When client is connected to server it runs a application".exe". Client is made to kill the process of some application by name. I made a timer for kill the process all the time client is running. When a process is killed client sends to server the IP from pc where process was killed and HWID code: byte[] outStream = System.Text.Encoding.ASCII.GetBytes(getUniqueID("C"));
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush(); and server recive on a listbox the ip and hwid. Well i'm thinking to do so . Example: On this recive message code where i get the HWID from client encoder.GetString(message, 0, bytesRead) to do something like:
if (encoder.GetString(message, 0, bytesRead) = LoadBlockHWID(new FileInfo(#"c:\testfileHWID.txt")));
{
//Code to block connection from specified IP on hwid.
}
I whant that server should not let the client connect to server by HWID. I think I must edit server to see ip and hwid connected and client to send hwid when connected.
Load your HWID into a List/Dictionary by reading your file before you start accepting connections.
in your code where you get tcpClient.Client.RemoteEndPoint, extract just the IPAddress out of that.
Then compare the IPAddress to the block list and if it matches, then see if the HWID matches if that matches then don't perform the task otherwise just do it.
mBlockCheck = new SO15147104();
Here is an example for you. Just instantiate the class and in your line where you Might want to block a request, just
if (!mBlockCheck.BlockRequest(ip, hwid))
{
//Do the operation
}
This is the class code you should be able to figure out from this.
using System.Collections.Generic;
using System.IO;
using System.Net;
public class SO15147104
{
private List<string> HWIDLookup;
private List<IPAddress> IPAddressLookup;
public SO15147104()
{
HWIDLookup = LoadBlockHWID(new FileInfo(#"c:\testfileHWID.txt"));
IPAddressLookup = LoadBlockIPAddresses(new FileInfo(
#"c:\testfileIPAddresses.txt"));
}
public bool BlockRequest(IPAddress ip, string HWIDtoCheck)
{
if (IPAddressLookup.Contains(ip) &&
HWIDLookup.Contains(HWIDtoCheck.ToUpperInvariant().Trim()))
{
return true;
}
return false;
}
private List<IPAddress> LoadBlockIPAddresses(FileInfo fi)
{
List<IPAddress> result = new List<IPAddress>();
using (StreamReader sr = fi.OpenText())
{
while (!sr.EndOfStream)
{
IPAddress theIP = IPAddress.Any;
string thisLine = sr.ReadLine().Trim();
//This should allow IPv6 and IPv4 to be listed 1IP per Line
if (IPAddress.TryParse(thisLine, out theIP))
{
result.Add(theIP);
}
}
}
return result;
}
private List<string> LoadBlockHWID(FileInfo fi)
{
List<string> result = new List<string>();
using (StreamReader sr = fi.OpenText())
{
while (!sr.EndOfStream)
{
result.Add(sr.ReadLine().Trim().ToUpperInvariant());
}
}
return result;
}