Web Proxy Created in C# needing to prompt for authentication - c#

I worte a little Web Proxy program that uses a TcpListener, which listen on a specific port for web calls. Once it recieves a call it creates a socket, gets the header of the call, forwards it onto the web page requested, reads the response and returns it to the client doing the request. The proxy works lovely, but now I want to limit who has access to the net via the proxy by implimenting user names. How would I incorparate authentication onto my proxy?
Here is my code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
namespace WebProxy2
{
public partial class Form1 : Form
{
public bool proxyOn = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void log(string logText)
{
Application.DoEvents();
textBox1.Text += logText + "\r\n";
StreamWriter sw = new StreamWriter(#"c:\proxyLog.txt",true);
sw.WriteLine(logText);
sw.Close();
Application.DoEvents();
}
class WebProxy2
{
Socket clientSocket;
Form1 proxyGui;
Byte[] read = new byte[1024];
Byte[] Buffer = null;
Encoding ASCII = Encoding.ASCII;
const string HTTP_VERSION = "HTTP/1.0";
const string CRLF = "\r\n";
Byte[] RecvBytes = new Byte[4096];
public WebProxy2(Socket socket, Form1 form)
{
this.clientSocket = socket;
this.proxyGui = form;
}
public void run()
{
Application.DoEvents();
String clientmessage = " ", sURL = " ";
int bytes = readmessage(read, ref clientSocket, ref clientmessage);
if (bytes == 0)
{
return;
}
int index1 = clientmessage.IndexOf(' ');
int index2 = clientmessage.IndexOf(' ', index1 + 1);
if ((index1 == -1) || (index2 == -1))
{
throw new IOException();
}
proxyGui.log("Connecting to Site: " + clientmessage.Substring(index1 + 1, index2 - index1));
proxyGui.log("Connection from " + clientSocket.RemoteEndPoint);
string part1 = clientmessage.Substring(index1 + 1, index2 - index1);
int index3 = part1.IndexOf('/', index1 + 8);
int index4 = part1.IndexOf(' ', index1 + 8);
int index5 = index4 - index3;
sURL = part1.Substring(index1 + 4, (part1.Length - index5) - 8);
try
{
IPHostEntry IPHost = Dns.Resolve(sURL);
proxyGui.log("Request resolved: " + IPHost.HostName);
string[] aliases = IPHost.Aliases;
IPAddress[] address = IPHost.AddressList;
proxyGui.log(address[0].ToString());
IPEndPoint sEndpoint = new IPEndPoint(address[0], 80);
Socket IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPsocket.Connect(sEndpoint);
if (IPsocket.Connected)
proxyGui.log("Socket connect OK");
string GET = clientmessage;
Byte[] ByteGet = ASCII.GetBytes(GET);
IPsocket.Send(ByteGet, ByteGet.Length, 0);
Int32 rBytes = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
proxyGui.log("Recieved " + rBytes);
//Buffer = RecvBytes;
String strRetPage = null;
strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, rBytes);
while (rBytes > 0)
{
rBytes = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, rBytes);
}
IPsocket.Shutdown(SocketShutdown.Both);
IPsocket.Close();
sendmessage(clientSocket, strRetPage);
}
catch (Exception exc2)
{
proxyGui.log(exc2.ToString());
}
}
private int readmessage(byte[] ByteArray, ref Socket s, ref String clientmessage)
{
int bytes = s.Receive(ByteArray, 1024, 0);
string messagefromclient = Encoding.ASCII.GetString(ByteArray);
clientmessage = (String)messagefromclient;
return bytes;
}
private void sendmessage(Socket s, string message)
{
Buffer = new Byte[message.Length + 1];
int length = ASCII.GetBytes(message, 0, message.Length, Buffer, 0);
s.Send(Buffer, length, 0);
}
}
const int port = 8080;
TcpListener tcplistener = new TcpListener(port);
private void btnProxy_Click_1(object sender, EventArgs e)
{
proxyOn = true;
log("Listening on port " + port + " " + DateTime.Now.ToString());
tcplistener.Start();
while (proxyOn)
{
Application.DoEvents();
if (tcplistener.Pending())
{
Socket socket = tcplistener.AcceptSocket();
WebProxy2 webproxy = new WebProxy2(socket, this);
webproxy.run();
}
Application.DoEvents();
}
}
private void btnStop_Click_1(object sender, EventArgs e)
{
Application.DoEvents();
proxyOn = false;
tcplistener.Stop();
log("Proxy stopped !!! " + DateTime.Now.ToString());
Application.DoEvents();
}
}
}

It's not clear whether you've implemented your own HTTP proxy protocol (more or less a simple TCP redirection based on the Host header) or if you're using the standard HTTP proxy protocol.
If you go for the standard proxy (which is probably better, unless you have a good reason not to do so), you should be able to use the Proxy-Authenticate, Proxy-Authorization and Proxy-Authentication-Info headers instead of WWW-Authenticate, Authorization and Authentication-Info (respectively) for HTTP Basic or Digest authentication for example.

Related

TCP/IP communication between ESP8266 server and C # client WinForm application

I try to make communication between client / server .... In C # application as a client I send data to ESP serial monitor without problems, with the fact that I can only send data from the application to ESP. My request is how I send data from ESP server serial monitor
To C # application for example textbox
I tried some code examples, but I have a problem sending data from ESP server to C # application as client. Do you have any suggestions on how to solve my problem? Thank you for any reply. I attach codes.
ESP Server code:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//const char* ssid = "KTEEM"; // Skola
//const char* password = "88888888"; // Skola
//const char* ssid = "Mi A3"; // Ja
//const char* password = "44114144"; // Ja
const char* ssid = "Slavo"; //Domov
const char* password = "bubo2222"; //Domov
//const char* host = "192.168.0.111"; //ipWifiSkola
//const char* host = "192.168.43.39"; //ipWifiMobil
const char* host = "192.168.0.105"; //ipWifiDomov
//const int udpPort = 8080; //portserver
int newData;
String data;
WiFiServer server(5045);
WiFiClient client;
void setup()
{
Serial.begin(115200);
wifiConnect();
server.begin();
}
void loop() {
if (WiFi.status() != WL_CONNECTED)
{
wifiConnect();
}
client = server.available();
if(Serial.available())
{
String command = Serial.readStringUntil('\n');
client.print(command);
delay(300);
}
if (client){
String data;
Serial.println("Client connected");
while (client.connected()){
while(client.available()>0)
{
//data = client.readStringUntil('\n');
//Serial.println(data);
char c = client.read();
Serial.write(c);
}
delay(10);
}
client.stop();
Serial.println("Client Disconnected");
}
}
void wifiConnect()
{
WiFi.begin(ssid, password);
Serial.println("");
while (WiFi.status () != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
C# client code:
using System;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.IO;
namespace TCPIP_ESP
{
class TCPClient
{
public int HostPort = 5045;
public string HostDomov = "192.168.0.105"; //Skola
public string HostMobil = "192.168.43.39"; //Mobil
public string HostSkola = "192.168.0.111"; //Domov
private TcpClient tcpClient = new TcpClient();
public Thread W_Thread;
public Thread R_Thread;
public bool IsListening = true;
NetworkStream networkStream = null;
public StreamReader serverData;
public StreamWriter clientData;
private StreamWriter streamWriter;
public NetworkStream NetworkStream { get => networkStream; set => networkStream = value; }
public void SendData(Client c)
{
if (NetworkStream.CanWrite)
{
byte[] sendBytes = Encoding.ASCII.GetBytes(c.txtMsg.Text + "$");
NetworkStream.Write(sendBytes, 0, sendBytes.Length);
c.txtMsg.Text = string.Empty;
NetworkStream.Flush();
}
else if (!NetworkStream.CanWrite)
{
Console.WriteLine("You can not read data from this stream");
tcpClient.Close();
}
}
public void ReadData(Client c)
{
try
{
string returnData = null;
byte[] bytes = new byte[4096];
if (NetworkStream.CanRead)
{
int bytesRead = NetworkStream.Read(bytes, 0, bytes.Length);
returnData = Encoding.UTF8.GetString(bytes, 0, bytesRead);
Console.WriteLine("Data read ..." + returnData);
tcpClient.Close();
NetworkStream.Close();
}
else
{
Console.WriteLine("You cannot read data from this stream.");
tcpClient.Close();
NetworkStream.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void CreateConnection(Client c)
{
tcpClient.Connect(HostDomov, HostPort);
NetworkStream = tcpClient.GetStream();
streamWriter = new StreamWriter(NetworkStream);
c.lblChangeData.Text = "Client Socket Porgram - Server Connected ...";
tcpClient.ReceiveBufferSize = 1024;
tcpClient.SendBufferSize = 1024;
if (tcpClient.Connected)
{
c.checkBox1.BackColor = System.Drawing.Color.Green;
}
else
c.checkBox1.BackColor = System.Drawing.Color.Red;
}
public void Disconnect()
{
tcpClient.Dispose();
tcpClient.Close();
NetworkStream.Close();
}
public void msg(Client c, string mesg)
{
c.listBox_Receive.Text = c.txtMsg.Text + Environment.NewLine + " >> " + mesg;
}
}
}

How to make server client autodiscover over a lan

I have two project "Server" and "Client" that communicate over a LAN,
this my server code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ServerClientProject
{
public partial class FormServer : Form
{
private static Int32 port;
private static string filePath;
TcpListener server = new TcpListener(IPAddress.Any, port);
public FormServer()
{
InitializeComponent();
}
private void FormServer_Load(object sender, EventArgs e)
{
File.WriteAllText("path.misc","");
File.WriteAllText("nama.misc","");
filePath = readPath();
label1.Text = filePath;
label2.Text = readNama();
label3.Text = IPAddressCheck();
label4.Text = UNCPathing.GetUNCPath(readPath());
label5.Text = GetFQDN();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
}
private static string IPAddressCheck()
{
IPHostEntry IPAddr;
IPAddr = Dns.GetHostEntry(GetFQDN());
IPAddress ipString = null;
foreach (IPAddress ip in IPAddr.AddressList)
{
if (IPAddress.TryParse(ip.ToString(), out ipString) && ip.AddressFamily == AddressFamily.InterNetwork)
{
break;
}
}
return ipString.ToString();
}
public static string GetFQDN()
{
string domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName;
string hostName = Dns.GetHostName();
if (!hostName.EndsWith(domainName)) // if hostname does not already include domain name
{
hostName += "." + domainName; // add the domain name part
}
return hostName; // return the fully qualified name
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
lstProgress.Items.Add(e.UserState);
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if ((worker.CancellationPending == true))
{
e.Cancel = true;
}
else
{
try
{
// Set the TcpListener on port 1333.
port = 1337;
//IPAddress localAddr = IPAddress.Parse("127.0.0.1");
TcpListener server = new TcpListener(IPAddress.Any, port);
//label2.Text = IPAddressToString(ip);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while (true)
{
bw.ReportProgress(0, "Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
bw.ReportProgress(0, "Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
bw.ReportProgress(0, String.Format("Received: {0}", data));
if (data == "file")
{
// Process the data sent by the client.
data = String.Format("Request: {0}", data);
byte[] mssg = System.Text.Encoding.ASCII.GetBytes(label4.Text);
// Send back a response.
stream.Write(mssg, 0, mssg.Length);
bw.ReportProgress(0, String.Format("Sent: {0}", data));
bw.ReportProgress(0, String.Format("File path : {0}", label4.Text));
}
else if (data == "nama")
{
byte[] mssg = System.Text.Encoding.ASCII.GetBytes(readNama());
stream.Write(mssg, 0, mssg.Length);
}
else if (data == "ip")
{
byte[] mssg = System.Text.Encoding.ASCII.GetBytes(GetFQDN());
stream.Write(mssg, 0, mssg.Length);
}
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException se)
{
bw.ReportProgress(0, String.Format("SocketException: {0}", se));
}
}
}
private void FormServer_FormClosing(object sender, FormClosingEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
savePath(openFileDialog1.FileName.ToString());
saveNama(openFileDialog1.SafeFileName.ToString());
//folderBrowserDialog1.ShowDialog();
//savePath(folderBrowserDialog1.SelectedPath.ToString());
label1.Text = readPath();
label2.Text = readNama();
label4.Text = UNCPathing.GetUNCPath(readPath());
}
private void savePath(string fPath)
{
string sPath = "Path.misc";
File.WriteAllText(sPath, fPath);
}
private string readPath()
{
string readText = File.ReadAllText("Path.misc");
return readText;
}
private void saveNama(string nama)
{
string sNama = "Nama.misc";
File.WriteAllText(sNama, nama);
}
private string readNama()
{
string readText = File.ReadAllText("Nama.misc");
return readText;
}
}
}
and this my client
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class FormClient : Form
{
public FormClient()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = IPAddressCheck();
label2.Text = GetFQDN();
label3.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
public void msg(string mesg)
{
lstProgress.Items.Add(">> " + mesg);
}
public static string GetFQDN()
{
string domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName;
string hostName = Dns.GetHostName();
if (!hostName.EndsWith(domainName)) // if hostname does not already include domain name
{
hostName += "." + domainName; // add the domain name part
}
return hostName; // return the fully qualified name
}
private static string IPAddressCheck()
{
IPHostEntry IPAddr;
IPAddr = Dns.GetHostEntry(GetFQDN());
IPAddress ipString = null;
foreach (IPAddress ip in IPAddr.AddressList)
{
if (IPAddress.TryParse(ip.ToString(), out ipString) && ip.AddressFamily == AddressFamily.InterNetwork)
{
break;
}
}
return ipString.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
string message = textBox1.Text;
try
{
// 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.
Int32 port = 1337;
string IPAddr = textBox2.Text;
TcpClient client = new TcpClient(IPAddr, port); //Unsure of IP to use.
// 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.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
//lstProgress.Items.Add(String.Format("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);
if (message == "file")
{
lstProgress.Items.Add(String.Format("{0}", responseData));
fPath.getPath = (String.Format("{0}", responseData));
label4.Text = UNCPathing.GetUNCPath(fPath.getPath);
}
else if(message == "nama")
{
lstProgress.Items.Add(String.Format("{0}", responseData));
fPath.getNama = (String.Format("{0}", responseData));
}
// Close everything.
stream.Close();
client.Close();
}
catch (ArgumentNullException an)
{
lstProgress.Items.Add(String.Format("ArgumentNullException: {0}", an));
}
catch (SocketException se)
{
lstProgress.Items.Add(String.Format("SocketException: {0}", se));
}
}
private void button2_Click(object sender, EventArgs e)
{
//using (NetworkShareAccesser.Access(GetFQDN(), IPAddressCheck(), "arif.hidayatullah28#gmail.com", "971364825135win8"))
//{
// File.Copy("\\\\"+label1.Text+"\\TestFolder\\"+fPath.getNama+"", #"D:\movie\"+ fPath.getNama+"", true);
//}
}
private void button3_Click(object sender, EventArgs e)
{
string connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\ARIF-PC\aaaaaaaaaa\MsAccess.accdb; Jet OLEDB:Database Password=dbase;";
string cmdText = "SELECT kode, deskripsi, stok, Harga FROM [Barang] ORDER BY kode DESC";
OleDbConnection conn = new OleDbConnection(connString);
OleDbCommand cmd = new OleDbCommand(cmdText, conn);
try
{
conn.Open();
cmd.CommandType = CommandType.Text;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable barang = new DataTable();
da.Fill(barang);
dataGridView1.DataSource = barang;
}
finally
{
conn.Close();
}
}
}
}
but as you can see, I have to know the server ip address, is there a way to make the server and client autodiscover??
I've try this, worked with one PC but with a LAN it failed.
This that I've tried
Sorry form my bad English
On the client send a UDP broadcast 192.168.1.255 (this assumes you are operating on a class C network 192.168.1/24). The server then listens for the broadcast from any clients and then sends back a directed UDP packet to the client. The client is listening for this and decodes the packet which contains the address of the server.
This link C# How to do Network discovery using UDP Broadcast and some Google Fu will produce many examples of how to implement this.

C# network - My form(client program) doesn't show when I start server program

I'm developing a networking application.
The server program gives questions, then clients enters their answers.
Actually, both server program and client program were console program.
But, when I changed client program to Form program, It doesn't display. (ONLY WHEN I TURN ON SERVER PROGRAM!)
It works when i don't start server program.
Here's my server program code,
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Server
{
public class TaskInfo
{
public Socket client;
public int thread_num;
public int q_num;
public ManualResetEvent doneEvent;
public TaskInfo(Socket c, int n, int q, ManualResetEvent d)
{
client = c;
thread_num = n;
q_num = q;
doneEvent = d;
}
}
public class ServerTCP
{
static int num_client = 2;
static bool[] check_co_client = new bool[num_client];
static int num_co_client = 0;
static void ClientHandler(Object task_info)
{
TaskInfo ti = (TaskInfo)task_info;
// Casting of object
Socket client = (Socket)ti.client;
IPEndPoint endpoint = (IPEndPoint)client.RemoteEndPoint;
//Console.WriteLine("{0} connected at port {1}", endpoint.Address, endpoint.Port);
int index = ti.q_num;
byte[] buffer = new byte[256];
int byteRecv = 0;
string message = "";
string[] questions = new string[5];
questions[0] = "0. What is 5+6?";
questions[1] = "1. What is 1+3?";
questions[2] = "2. What is 5+3?";
questions[3] = "3. What is 1+1?";
questions[4] = "4. What is 9-5?";
string[] answers = new string[5];
answers[0] = "11";
answers[1] = "4";
answers[2] = "8";
answers[3] = "2";
answers[4] = "4";
try
{
// Send message to client
buffer = Encoding.ASCII.GetBytes(questions[index]);
client.Send(buffer, buffer.Length, SocketFlags.None);
// Receive data from client
byteRecv = client.Receive(buffer);
message = Encoding.ASCII.GetString(buffer, 0, byteRecv);
if (message == answers[ti.q_num])
{
check_co_client[ti.thread_num] = true;
}
else
{
check_co_client[ti.thread_num] = false;
}
ti.doneEvent.Set();
}
catch (SocketException se)
{
Console.WriteLine("{0}: {1} [{2}:{3}]", se.ErrorCode, se.Message, endpoint.Address, endpoint.Port);
}
finally
{
// Close socket
//client.Close();
}
}
public static void Main()
{
TcpListener listener = null;
try
{
// Create new instance and start listening
listener = new TcpListener(IPAddress.Any, 8080);
listener.Start();
Console.WriteLine("<Waiting for clients connection>");
// Accept the client connection
Socket[] client = new Socket[num_client];
int count = 0;
while (count < num_client)
{
client[count] = listener.AcceptSocket();
count++;
}
ManualResetEvent[] doneEvents = new ManualResetEvent[num_client];
// Start threads
Thread[] t = new Thread[num_client];
for (int q_num = 0; q_num < 5; q_num++)
{
for (int i = 0; i < num_client; i++)
{
doneEvents[i] = new ManualResetEvent(false);
TaskInfo ti = new TaskInfo(client[i], i, q_num, doneEvents[i]);
t[i] = new Thread(ClientHandler);
t[i].Start(ti);
}
WaitHandle.WaitAll(doneEvents);
Thread.Sleep(2000);
// count clients who enter correct answer
for (int index = 0; index < num_client; index++)
{
if (check_co_client[index])
{
num_co_client++;
}
}
Console.WriteLine("number of correct answers: {0}", num_co_client);
num_co_client = 0;
}
}
catch (SocketException se)
{
Console.WriteLine("Error Code: {0}", se.ErrorCode);
Console.WriteLine("Message: {0}", se.Message);
}
finally
{
listener.Stop();
}
Console.ReadLine(); // Pause for IDE
}
}
}
and here's my client program code,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Client_Form
{
public partial class Client_Form : Form
{
TcpClient client = null;
NetworkStream stream = null;
int count = 0;
public Client_Form()
{
InitializeComponent();
Start_Program();
}
private void Start_Program()
{
try
{
// Connect to server
client = new TcpClient("127.0.0.1", 8080);
//Console.WriteLine("<Connected to server>");
textBox.Text = "<Connected to server>";
stream = client.GetStream();
byte[] buffer = new byte[256];
int byteRecv = 0;
string message = "";
int q_count = 5;
while (count < q_count)
{
while ((byteRecv = stream.Read(buffer, 0, buffer.Length)) == 0)
{
textBox.Text = "Waiting for other client";
Thread.Sleep(3000);
}
// Get data from server
//byteRecv = stream.Read(buffer, 0, buffer.Length);
message = Encoding.ASCII.GetString(buffer, 0, byteRecv);
Co_Game_Question.Text = message;
}
// Close stream and connection
stream.Close();
client.Close();
//Console.WriteLine("<Connection closed>");
textBox.Text = "<Connection closed>";
}
catch (SocketException se)
{
//Console.WriteLine("Error: {0}", se.SocketErrorCode);
//Console.WriteLine("Error Code: {0}", se.ErrorCode);
//Console.WriteLine("Message: {0}", se.Message);
textBox.Text = "Error Message: " + se.Message;
}
}
private void Btn_Enter_Click(object sender, EventArgs e)
{
// Send message to server
//Console.Write("Answer {0}> ", count);
//textBox.Text = "Answer " + count + "> ";
byte[] data = Encoding.ASCII.GetBytes(User_answer_box.Text);
stream.Write(data, 0, data.Length);
count++;
}
}
}
How can I solve this problem??
Thanks for reading my question!
Since you are already using NetworkStream, fixing the client code is easy. Just switch over to the async/await idiom:
namespace Client_Form
{
public partial class Client_Form : Form
{
TcpClient client = null;
NetworkStream stream = null;
int count = 0;
public Client_Form()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
// Handling the network operations after the form loads ensures
// that the asynchronous operations will come back to the main
// thread as desired.
// Ignore returned Task
var _ = Start_Program();
}
private async void Start_Program()
{
try
{
// Connect to server
client = await Task.Run(() => new TcpClient("127.0.0.1", 8080));
textBox.Text = "<Connected to server>";
stream = client.GetStream();
byte[] buffer = new byte[256];
int q_count = 5;
while (count < q_count)
{
textBox.Text = "Waiting for other client";
// Get data from server
int byteRecv = await stream.ReadAsync(buffer, 0, buffer.Length);
string message = Encoding.ASCII.GetString(buffer, 0, byteRecv);
Co_Game_Question.Text = message;
}
// Close stream and connection
stream.Close();
client.Close();
textBox.Text = "<Connection closed>";
}
catch (SocketException se)
{
textBox.Text = "Error Message: " + se.Message;
}
}
}
}
Now, that said, you had and still have some other bugs. First, your original code had a loop that read from the stream until the return value was 0. All that's going to do is consume the data in the stream without processing any of it. Very bad. I removed that bug completely in the example above.
Second, you are not checking the return value of the read. TCP guarantees only one thing: that if you receive any data, the bytes that you receive are in the same order in which they were sent. In particular, there are no guarantees about how many bytes you'll receive in any given call to Read(). If the remote endpoint sends 100 bytes, you could receive all 100 bytes all at once, or you could receive 1 byte at a time in 100 calls to Read().
(Well, actually that's highly unlikely to ever happen...but it's not prohibited by the TCP contract, and in any case if you assume it's true you'll write correct code).
That's really a whole other question. The above will get your Forms program back to working, in that you'll actually be able to see the Form and interact with it. And the network code might even seem to work for awhile. But eventually you'll get a partial message, or multiple messages combined into one, or some other variation on that theme.
When that happens, IMHO one of the easiest ways to fix that in a scenario like yours is to switch to a line-based data scheme. I.e. wrap the NetworkStream object in StreamReader and StreamWriter objects, and use the ReadLineAsync() method to receive data instead of the NetworkStream.Read() method. Regardless, feel free to post another question when you come to that bridge. :)

how to send and receive string continously using sockets in c#

Basically what i am stuck at is , i want my client to send data continously and server to read from client as it sends, like when i send "2" it should read "2" and display and so on it should continue to read as long as i send from the client, i can stop or exit whenever i press some different character,.
what i have acheived is not continous, i send from client 2 and server receives 2 and then it is stopped, i want to send them continously , i am pasting below my code,
client.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Client
{
class Program
{
const int port = 8001;
const string ip = "127.0.0.1";
const int maxBuffer = 100;
static void Main(string[] args)
{
try
{
while (true)
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("127.0.0.1", 8001);
// use the ipaddress as in the server program
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String str = Console.ReadLine();
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
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]));
Console.ReadLine();
tcpclnt.Close();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
}
server.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Server
{
class Program
{
const int port = 8001;
const string ip = "127.0.0.1";
const int maxBuffer = 100;
static void Main(string[] args)
{
try
{
IPAddress ipAd = IPAddress.Parse("127.0.0.1");
// use local m/c IP address, and
// use the same in the client
while (true)
{
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 8001);
/* Start Listeneting at the specified port */
myList.Start();
Console.WriteLine("The server is running at port 8001...");
Console.WriteLine("The local End point is :" +
myList.LocalEndpoint);
Console.WriteLine("Waiting for a connection.....");
Socket s = myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
byte[] b = new byte[100];
int k = s.Receive(b);
Console.WriteLine("Recieved...");
for (int i = 0; i < k; i++)
Console.Write(Convert.ToChar(b[i]));
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
Console.ReadLine();
/* clean up */
s.Close();
myList.Stop();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
}
Any help will be appreciated
Thanks :)
By using MultiThread you can send and receive message between client and server continuously.
Server side example:
IPAddress[] ipAdd = Dns.GetHostAddresses("192.168.1.38");
IPAddress ipAddress = ipAdd[0];
TcpListener serverSocket = new TcpListener(ipAddress, 8888);
TcpClient clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
notifyIcon.ShowBalloonTip(5000, "Server Notification", " >> Server Started.", wform.ToolTipIcon.Info);
counter = 0;
while (true)
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
if (clientsList.ContainsKey(dataFromClient))
{
continue;
}
else
{
clientsList.Add(dataFromClient, clientSocket);
}
string onlineUsers = "";
foreach (DictionaryEntry item in clientsList)
{
onlineUsers += item.Key.ToString() + ";";
}
onlineUsers = onlineUsers.Remove(onlineUsers.Length - 1);
Broadcast.BroadcastSend(dataFromClient + " joined. |" + onlineUsers, dataFromClient, ref clientsList, false, false);
notifyIcon.ShowBalloonTip(5000,"Client Notification", dataFromClient + " joined.", wform.ToolTipIcon.Info);
HandleClient client = new HandleClient();
client.StartClient(clientSocket, dataFromClient, clientsList, notifyIcon);
}
More details
Ignore my earlier answer
The problem is that the server is waiting for user response in console after sending acknowledgement.
Console.ReadLine();
Just comment out this line in your original program.
And add a exit condition by checking the input.
Also as the previous poster suggest, make it thread based if you want multiple clients connecting to this server simultaneously.

How to receive multiple packets using UDP at a single socket in a single array

I need to receive multiple packets but I am getting only one packet and i want the values of the next should overwrite the values of the previous packet in the same array
For example the sample of my code is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using microLCC;
namespace A2LDFCSolver
{
public partial class Form1 : Form
{
int m;
byte[] data = new byte[1024];
//byte[] buffer = new byte[10];
IPEndPoint endpoint = new IPEndPoint(IPAddress.Loopback, 1235);
Socket newsocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint sen = new IPEndPoint(IPAddress.Loopback, 5001);
microLCC.microLCC uLC = new microLCC.microLCC();
EndPoint tmp;
StateObject obj = new StateObject();
int count = 0;
int cout = 0;
public static ManualResetEvent allDone = new ManualResetEvent(false);
public Form1()
{
InitializeComponent();
newsocket.Bind(endpoint);
tmp = (EndPoint)sen;
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void bw_Reset(object sender, RunWorkerCompletedEventArgs e)
{
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textBox1.Text = "Message Recieved" + count.ToString();
}
private void bw_doit(object sender, DoWorkEventArgs e)
{
StateObject state = new StateObject();
while (true)
{
allDone.Reset();
//newsocket.ReceiveFrom(data, 0, 40, SocketFlags.None, ref tmp);
newsocket.BeginReceive(data, 0, 40, 0, new AsyncCallback(ReadCallback), state);
backgroundWorker1.ReportProgress(0);
allDone.WaitOne();
}
}
protected void ReadCallback(IAsyncResult ar)
{
allDone.Set();
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
//Socket newsocket = (Socket)ar.AsyncState;
//newsocket.EndReceive(ar);
count = count + 1;
for (m = 0; m <= 17; m = m + 1)
{
if (m <= 7)
{
uLC.setDAC_raw(m, data[m]);
}
if (m >= 8 && m <= 14)
{
if (data[m] == 1)
{
uLC.setRelay((m - 7), true);
}
if (data[m] == 0)
{
uLC.setRelay((m - 7), false);
}
}
if (m == 15)
{
uLC.setEPM_CaS(data[m]);
}
if (m == 16)
{
uLC.setEPM_CrS(data[m]);
}
}
send(newsocket);
}
private void send(Socket newsocket)
{
StateObject state = new StateObject();
byte[] buffer = new byte[1024];
for (int i = 0; i < 6; i++)
{
buffer[i] = (Byte)uLC.getADC(i);
}
newsocket.BeginSendTo(buffer, 0, 7, 0, sen,new AsyncCallback(SendCallback), state);
}
protected void SendCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int s = newsocket.EndSendTo(ar);
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
}
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public StringBuilder sb = new StringBuilder();
}
Here I am receiving the values only one time in my data array but if I need to receive more than one packets in the single array then how can I do that .
Please help me
Thanks in advance..
IPEndPoint sen = new IPEndPoint(IPAddress.Loopback, 5001);
EndPoint tmp = (EndPoint)sen;
newsocket.Bind(endpoint);
int count=0;
while(newsocket.Available>0 && count<data.Length)
{
count+= newsocket.ReceiveFrom(data,count, 40, SocketFlags.None, ref tmp);
}

Categories