Get all bytes from stream - c#

I'm writing a proxy in c# and I wrote this method to get bytes from the stream but after looking at answer in this thread : Proxy won't work in chrome and only partly in firefox I realize that I do not get all the bytes. How can I solve this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace LexProxy
{
class ProxyServer
{
private TcpListener tcpListener;
public ProxyServer()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.tcpListener.Start();
while (true)
{
Console.Write("Waiting for a connection... ");
TcpClient client = tcpListener.AcceptTcpClient();
Thread thread = new Thread(delegate()
{
Serve(client);
});
thread.Start();
}
}
private void Serve(TcpClient client)
{
Console.WriteLine("Connected!");
NetworkStream stream = client.GetStream();
byte[] request = GetBytesFromStream(stream, client.ReceiveBufferSize);
if (request != null)
{
string requestString = System.Text.Encoding.UTF8.GetString(request);
string[] requestParts = requestString.Split(' ');
if (requestParts.Length >= 2)
{
string method = requestParts[0];
if (!requestParts[1].Contains("http://") && !requestParts[1].Contains("https://"))
requestParts[1] = "http://" + requestParts[1];
Uri uri = new Uri(requestParts[1], UriKind.RelativeOrAbsolute);
string host = StringUtils.ReplaceFirst(uri.Host, "www.", "");
int port = uri.Port;
byte[] response = getResponse(host, port, request);
if (response != null)
stream.Write(response, 0, response.Length);
client.Close();
}
}
}
private byte[] getResponse(string host, int port, byte[] request)
{
TcpClient client = new TcpClient(host, port);
NetworkStream stream = client.GetStream();
stream.Write(request, 0, request.Length);
byte[] response = GetBytesFromStream(stream, client.ReceiveBufferSize);
return response;
}
private byte[] GetBytesFromStream(NetworkStream stream, int bufferSize)
{
Byte[] bytes = new Byte[bufferSize];
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
return bytes;
}
return null;
}
}
}

Try out this sample Proxy Server instead:
http://times.imkrisna.com/2011/08/simple-http-proxy-server-c-source-code/

You're doing this wrong. Instead of trying to gather the entire response before sending it downstream, you should just be copying bytes as they arrive. No need to add latency.
But note that the code you have written in getAllBytesFromStream() is nonsense. You have a while loop with an unconditional return statement in it. How is that ever going to execute more than once?

Related

create Proxy server using c#

I want to create a proxy server, but I'm having trouble communicating with ssl
I've tried a lot and failed sites that support http don't work it's just preparing the connection it works (google)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
using System.Diagnostics;
using System.Net.Sockets;
using System.IO;
using System.Net.Http.Headers;
using System.Runtime.Remoting.Messaging;
using RestSharp;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Data;
using System.Security.Policy;
using System.Security.Authentication;
using System.Runtime.ConstrainedExecution;
namespace Proxy
{
internal class Program
{
public static HttpListener listener;
static void Main(string[] args)
{
var ip = IPAddress.Parse("127.0.0.1");
Start(ip, 2020);
}
public static void Start(IPAddress ip, int port)
{
try
{
serverCertificate = X509Certificate.CreateFromCertFile("C:\\Users\\AK\\Desktop\\FiddlerRoot.cer");
TcpListener listener = new TcpListener(ip, port);
listener.Start(100);
while (true)
{
Socket client = listener.AcceptSocket();
IPEndPoint rep = (IPEndPoint)client.RemoteEndPoint;
Thread thread = new Thread(ThreadHandleClient);
thread.Start(client);
}
listener.Stop();
}
catch (Exception ex)
{
Console.WriteLine("START: " + ex.Message);
}
}
public static void ThreadHandleClient(object o)
{
try
{
Socket client = (Socket)o;
Console.WriteLine("===================================================================================");
Console.WriteLine("=========================Request=========================================");
Console.WriteLine("===================================================================================");
NetworkStream ns = new NetworkStream(client);
byte[] buffer = new byte[2048];
int rec = 0;
string data = "";
do
{
rec = ns.Read(buffer, 0, buffer.Length);
data += Encoding.ASCII.GetString(buffer, 0, rec);
} while (rec == buffer.Length);
Console.WriteLine(data);
Console.WriteLine("===================================================================================");
Console.WriteLine("=========================URL=========================================");
Console.WriteLine("===================================================================================");
string line = data.Replace("\r\n", "\n").Split(new string[] { "\n" }, StringSplitOptions.None)[0];
string UrlString = line.Split(new string[] { " " }, StringSplitOptions.None)[1];
var url = UrlString.EndsWith(":443") ? "https://" + UrlString.Replace(":443", "") : UrlString.Replace(":80", "");
Uri uri = new Uri(url);
Console.WriteLine(url);
Console.WriteLine("===================================================================================");
Console.WriteLine("=========================Response=========================================");
Console.WriteLine("===================================================================================");
if (uri.Scheme == "https")
{
Https(client, uri.Host, data);
}
else
{
Http(client, uri.Host, data);
}
}
catch (Exception ex)
{
Console.WriteLine("Error occured: " + ex.Message);
}
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate,X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
private static void Https( Socket clients,string Url,string datas)
{
TcpClient client = new TcpClient(Url, 443);
SslStream sw = new SslStream(client.GetStream());
sw.AuthenticateAsClient(Url);
string[] headers = datas.Split('\n');
foreach (string header in headers)
{
byte[] data = Encoding.UTF8.GetBytes(header + "\n\n");
sw.Write(data);
}
TcpClient el = new TcpClient();
el.Client = clients;
SslStream Send = new SslStream(el.GetStream(), true);
var cert = new X509Certificate2(sw.RemoteCertificate);
Send.AuthenticateAsServer(cert, true,true);
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sw.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
Send.Write(buffer,0, bytes);
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
client.Close();
Console.WriteLine(messageData.ToString());
Console.WriteLine("===================================================================================");
// This is where you read and send data
}
private static void Http(Socket clients, string Url, string datas)
{
IPHostEntry hostEntry;
hostEntry = Dns.GetHostEntry(Url);
EndPoint hostep = new IPEndPoint(hostEntry.AddressList[0], 80);
Socket sock = new Socket(hostEntry.AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.Tcp);
datas = datas.Replace("http://"+Url, "");
sock.Connect(hostep);
string[] headers=datas.Split('\n');
foreach (string header in headers)
{
byte[] data = Encoding.UTF8.GetBytes(header+"\n\n");
sock.Send(data, 0, data.Length, SocketFlags.None);
}
byte[] bytes = new byte[2020];
int Rs = 0;
StringBuilder builder = new StringBuilder();
do
{
Rs=sock.Receive(bytes);
clients.Send(bytes, Rs, (SocketFlags)0);
builder.Append(Encoding.UTF8.GetString(bytes,0,Rs));
} while (Rs !=0);
Console.WriteLine(builder.ToString());
Console.WriteLine("===================================================================================");
}
}
public class Certificate
{
public static X509Certificate2 GetCertificate()
{
return new X509Certificate2(Properties.Resources.FiddlerRoot);
}
}
}
I've tried a lot and failed sites that support http don't work, it's just preparing the connection it works (google).

My .NET tcp server application will randomly use 100% CPU

I have a serious issue with my .NET server application. In production, the application will reach 100% CPU usage and get stuck there until I restart the server. It seems completely random. Sometimes it will happen 10 minutes after I start the server. Sometimes a week after I start the server. There are no logs that indicate what causes it either. But I am guessing I wrote the TCP client/server wrong and there is some edge case that can cause this. I believe this issue didn't start happening until I added this TCP client/server. I say client and server because this class does both and I actually have two different server applications that use it to communicate to each other and they both experience this issue randomly (not at the same time). Also side note user clients from all over the world use this same TCP client/server class: Bridge to connect to the server as well.
Is there anything I can do to try and figure out what's causing this? It's a .NET console app running on a Linux VM on Google Cloud Platform.
If you are knowledgable with .NET TCP classes then perhaps you can find an issue with this code?
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SBCommon
{
public class Bridge<T> where T : struct, IConvertible
{
public Dictionary<int, BridgeHandler> bridgeHandlers;
public ClientHandler clientHandler;
TcpListener server = null;
public Bridge(int port, Dictionary<int, BridgeHandler> bridgeHandlers)
{
server = new TcpListener(IPAddress.Any, port);
server.Start();
this.bridgeHandlers = bridgeHandlers;
Logging.Info($"bridge listener on address {IPAddress.Any} port {port}");
}
public void StartListener()
{
try
{
Logging.Info($"Starting to listen for TCP connections");
while (true)
{
Logging.Debug("TCP client ready");
TcpClient client = server.AcceptTcpClient();
Logging.Debug("TCP client connected");
Thread t = new Thread(new ParameterizedThreadStart(HandleConnection));
t.Start(client);
}
}
catch (SocketException e)
{
Logging.Error($"SocketException: {e}");
server.Stop();
}
}
public void HandleConnection(object obj)
{
TcpClient client = (TcpClient)obj;
client.ReceiveTimeout = 10000; // adding this to see if it fixes the server crashes
var stream = client.GetStream();
try
{
if (stream.CanRead)
{
byte[] messageLengthBytes = new byte[4];
int v = stream.Read(messageLengthBytes, 0, 4);
if (v != 4)
{
// this is happening and then the server runs at over 100% so adding lots of logging to figure out what's happening
StringBuilder sb = new StringBuilder($"could not read incoming message. Read {v} bytes");
try
{
sb.Append($"\nfrom {(IPEndPoint)client.Client.RemoteEndPoint}");
}
catch (Exception e)
{
sb.Append($"\ncould not get client's IP address because {e}");
}
sb.Append($"\nclient.Available: {client.Available}");
sb.Append($"\nclient.SendBufferSize: {client.SendBufferSize}");
Logging.Error(sb.ToString());
stream.Close();
client.Close();
stream.Dispose();
client.Dispose();
return;
}
int messageLength = BitConverter.ToInt32(messageLengthBytes, 0);
int readPos = 0;
byte[] recievedData = new byte[messageLength];
while (readPos < messageLength)
{
int size = Math.Min(messageLength - readPos, client.ReceiveBufferSize);
v = stream.Read(recievedData, readPos, size);
readPos += v;
}
Bits incoming = new Bits(recievedData);
incoming.InitReadableBuffer();
int packetType = incoming.ReadInt();
Bits outgoing;
if (packetType == int.MaxValue)
{
Logging.Info($"recieved client handler message");
outgoing = clientHandler(incoming, client);
}
else
{
if (bridgeHandlers.ContainsKey(packetType))
{
Logging.Info($"recieved {(T)(object)packetType}");
outgoing = bridgeHandlers[packetType](incoming);
}
else
{
Logging.Error($"recieved unhandled packetType {packetType}!!!!!");
return;
}
}
if (outgoing != null)
{
#region send response
byte[] sendData = new byte[outgoing.Length() + 4];
// first write the length of the message
BitConverter.GetBytes(outgoing.Length()).CopyTo(sendData, 0);
// then write the message
outgoing.ToArray().CopyTo(sendData, 4);
stream.Write(sendData, 0, sendData.Length);
outgoing.Dispose();
#endregion
}
else
{
byte[] sendData = new byte[4];
BitConverter.GetBytes(0).CopyTo(sendData, 0);
stream.Write(sendData, 0, sendData.Length);
}
}
else
{
Logging.Info("Sorry. You cannot read from this NetworkStream.");
}
}
catch (Exception e)
{
Logging.Error($"Exception: {e}");
stream.Close();
client.Close();
stream.Dispose();
client.Dispose();
}
}
public static void SendTCPmessageFireAndForget(IPEndPoint iPEndPoint, Bits bits)
{
Task.Run(() =>
{
SendTCPmessage(iPEndPoint, bits, out _);
bits.Dispose();
});
}
public static async Task<Bits> SendTCPmessageAsync(IPEndPoint iPEndPoint, Bits bits)
{
TcpClient client = new TcpClient();
client.Connect(iPEndPoint);
NetworkStream stream = client.GetStream();
stream.WriteTimeout = 5000;
stream.ReadTimeout = 5000;
// Send the message
byte[] bytes = new byte[bits.Length() + 4];
BitConverter.GetBytes(bits.Length()).CopyTo(bytes, 0); // write length of message
bits.ToArray().CopyTo(bytes, 4);
await stream.WriteAsync(bytes, 0, bytes.Length);
// Read the response
byte[] messageLengthBytes = new byte[4];
int v = await stream.ReadAsync(messageLengthBytes, 0, 4);
if (v != 4) throw new Exception("could not read incoming message");
int messageLength = BitConverter.ToInt32(messageLengthBytes, 0);
if (messageLength > 0)
{
int readPos = 0;
byte[] recievedData = new byte[messageLength];
while (readPos < messageLength)
{
int size = Math.Min(messageLength - readPos, client.ReceiveBufferSize);
v = await stream.ReadAsync(recievedData, readPos, size);
readPos += v;
}
stream.Close();
client.Close();
bits = new Bits(recievedData);
}
else bits = null;
return bits;
}
public static void SendTCPmessage(IPEndPoint iPEndPoint, Bits bits, out Bits responseBits)
{
try
{
TcpClient client = new TcpClient();
client.Connect(iPEndPoint);
NetworkStream stream = client.GetStream();
stream.WriteTimeout = 50000;
stream.ReadTimeout = 50000;
// Send the message
byte[] bytes = new byte[bits.Length() + 4];
BitConverter.GetBytes(bits.Length()).CopyTo(bytes, 0); // write length of message
bits.ToArray().CopyTo(bytes, 4);
stream.Write(bytes, 0, bytes.Length);
// Read the response
byte[] messageLengthBytes = new byte[4];
if (stream.Read(messageLengthBytes, 0, 4) != 4) throw new Exception("could not read incoming message");
int messageLength = BitConverter.ToInt32(messageLengthBytes, 0);
if (messageLength > 0)
{
int readPos = 0;
byte[] recievedData = new byte[messageLength];
while (readPos < messageLength)
{
int size = Math.Min(messageLength - readPos, client.ReceiveBufferSize);
int v = stream.Read(recievedData, readPos, size);
readPos += v;
}
stream.Close();
client.Close();
responseBits = new Bits(recievedData);
}
else responseBits = null;
}
catch (Exception e)
{
Logging.Error($"Exception: {e}");
responseBits = null;
}
}
}
public delegate Bits BridgeHandler(Bits incoming);
public delegate Bits ClientHandler(Bits incoming, TcpClient client);
}
Notes:
Bits is a class I use for serialization.
You can see in StartListener that I start a thread for every incoming connection
I also use while (true) and AcceptTcpClient to accept tcp connections. But maybe I shouldn't be doing it that way?
I read the first 4 bytes as an int from every packet to determine what kind of packet it is.
then I continue to to read the rest of the bytes until I have read all of it.
There is a lot wrong with your existing code, so it's hard to know what exactly is causing the issue.
Mix of async and non-async calls. Convert the whole thing to async and only use those, do not do sync-over-async.
Assuming stream.Read is actually returning the whole value in one call.
Lack of using in many places.
Repetitive code which should be refactored into functions.
Unsure what the use of bits.ToArray is and how efficient it is.
You may want to add CancellationToken to be able to cancel the operations.
Your code should look something like this:
public class Bridge<T> : IDisposable where T : struct, IConvertible
{
public Dictionary<int, BridgeHandler> bridgeHandlers;
public ClientHandler clientHandler;
TcpListener server;
public Bridge(int port, Dictionary<int, BridgeHandler> bridgeHandlers)
{
server = new TcpListener(IPAddress.Any, port);
this.bridgeHandlers = bridgeHandlers;
Logging.Info($"bridge listener on address {IPAddress.Any} port {port}");
}
public async Task StartListener()
{
try
{
Logging.Info($"Starting to listen for TCP connections");
server.Start();
while (true)
{
Logging.Debug("TCP client ready");
TcpClient client = await server.AcceptTcpClientAsync();
Logging.Debug("TCP client connected");
Task.Run(async () => await HandleConnection(client));
}
}
catch (SocketException e)
{
Logging.Error($"SocketException: {e}");
}
finally
{
if (listener.Active)
server.Stop();
}
}
public async Task HandleConnection(TcpClient client)
{
using client;
client.ReceiveTimeout = 10000; // adding this to see if it fixes the server crashes
using var stream = client.GetStream();
try
{
var incoming = await ReadMessageAsync(stream);
incoming.InitReadableBuffer();
int packetType = incoming.ReadInt();
Bits outgoing;
if (packetType == int.MaxValue)
{
Logging.Info($"recieved client handler message");
outgoing = clientHandler(incoming, client);
}
else
{
if (bridgeHandlers.TryGetValue(packetType, handler))
{
Logging.Info($"recieved {(T)(object)packetType}");
outgoing = handler(incoming);
}
else
{
Logging.Error($"recieved unhandled packetType {packetType}!!!!!");
return;
}
}
using (outgoing);
await SendMessageAsync(stream, outgoing);
}
catch (Exception e)
{
Logging.Error($"Exception: {e}");
}
}
public static void SendTCPmessageFireAndForget(IPEndPoint iPEndPoint, Bits bits)
{
Task.Run(async () =>
{
using (bits)
await SendTCPmessageAsync(iPEndPoint, bits);
});
}
public static async Task<Bits> SendTCPmessageAsync(IPEndPoint iPEndPoint, Bits bits)
{
using TcpClient client = new TcpClient();
await client.ConnectAsync(iPEndPoint);
using NetworkStream stream = client.GetStream();
stream.WriteTimeout = 5000;
stream.ReadTimeout = 5000;
await SendMessageAsync(stream, bits);
return await ReadMessageAsync(stream);
}
}
private async Task SendMessageAsync(Stream stream, Bits message)
{
var lengthArray = message == null ? new byte[4] : BitConverter.GetBytes(bits.Length());
await stream.WriteAsync(lengthArray, 0, lengthArray.Length); // write length of message
if (message == null)
return;
var bytes = bits.ToArray();
await stream.WriteAsync(bytes, 0, bytes.Length);
}
private async Task<Bits> ReadMessageAsync(Stream stream)
{
var lengthArray = new byte[4];
await FillBuffer(stream, lengthArray);
int messageLength = BitConverter.ToInt32(lengthArray, 0);
if (messageLength == 0)
return null;
byte[] receivedData = new byte[messageLength];
await FillBuffer(stream, receivedData);
bits = new Bits(receivedData);
return bits;
}
private async Task FillBuffer(Stream stream, byte[] buffer)
{
int totalRead = 0;
int bytesRead = 0;
while (totalRead < buffer.Length)
{
var bytesRead = await stream.ReadAsync(lengthArray, totalRead, buffer.Length - totalRead);
totalRead += bytesRead;
if(bytesRead <= 0)
throw new Exception("Unexpected end of stream");
}
}

Ident server not returning Identification on port 113

I am trying to program an ident sever to deal with the identity protocol requests from an irc server that I am programming an irc client for. The problem is I try to print to the screen the what I receive but nothing prints. I am not getting an error code.
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 IdentityClass
{
private const int bufSize = 32;
public void IdentityRequest() {
TcpListener listener = null;
int port = 113;
IPEndPoint hostInfo = new IPEndPoint(IPAddress.Any, 113);
listener = new TcpListener(hostInfo);
listener.Start();
byte[] rcvBuffer = new byte[bufSize];
int rec;
for (; ; )
{
TcpClient client = null;
NetworkStream netStream = null;
client = listener.AcceptTcpClient();
if (listener.Pending())
{
Console.WriteLine("Connection was made");
}
netStream = client.GetStream();
//byte[] rcvBuffer = new byte[bufSize];
rec = netStream.Read(rcvBuffer, 0, rcvBuffer.Length);
Array.Resize(ref rcvBuffer, rec);
Console.WriteLine(Encoding.ASCII.GetString(rcvBuffer));
netStream.Close();
client.Close();
}
}
}
}
This is a very basic implementation of an ident server
Obviously it only accepts one connection and closes
Note you'll need to have a port mapped through your router for this to work
public class Ident
{
private readonly TcpListener _listener;
private readonly string _userId;
public Ident(string userId)
{
_userId = userId;
_listener = new TcpListener(IPAddress.Any, 113);
}
public void Start()
{
Console.WriteLine("Ident started");
_listener.Start();
var client = _listener.AcceptTcpClient();
_listener.Stop();
Console.WriteLine("Ident got a connection");
using (var s = client.GetStream())
{
var reader = new StreamReader(s);
var str = reader.ReadLine();
var writer = new StreamWriter(s);
Console.WriteLine("Ident got: " + str + ", sending reply");
writer.WriteLine(str + " : USERID : UNIX : " + _userId);
writer.Flush();
Console.WriteLine("Ident sent reply");
}
Console.WriteLine("Ident server exiting");
}
}

Infrared command with pocket pc

i have an infrared remote control and i want replace this with my PPC.
My Mitac P550 has an infrared serial port but i dont know how to retrieve and resend the sequence of byte.....
It's possible get the data with SerialPort component of .net for this pourpose?
Thanks
You need to write two (2) methods and install them on each end of your communications: A Send and a Receive.
A generic Send routine would send a message to some host listening on a given port number. Here is a simple example:
public static void Send(string message, string host, int port) {
if (!String.IsNullOrEmpty(message)) {
if (port < 80) {
port = DEF_PORT;
}
Byte[] data = Encoding.ASCII.GetBytes(message);
using (var client = new TcpClient(host, port)) {
var stream = client.GetStream();
stream.Write(data, 0, data.Length);
stream.Close();
client.Close();
}
}
}
A generic Receive routine would need to know the port number to listen on and should return the data that it receives. Here is a simple example of it:
public static string Receive(int port) {
string data = null;
listener = new TcpListener(IPAddress.Any, port);
listener.Start();
using (var client = listener.AcceptTcpClient()) { // waits until data is avaiable
int MAX = client.ReceiveBufferSize;
var stream = client.GetStream();
Byte[] buffer = new Byte[MAX];
int len = stream.Read(buffer, 0, MAX);
if (0 < len) {
data = Encoding.UTF8.GetString(buffer, 0, len);
}
stream.Close();
client.Close();
}
return data;
}
Here is the full class code that I used for this:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace AcpMobile5 {
class TestClass1 : Form {
public const int DEF_PORT = 8000;
private static TcpListener listener;
public static string Receive(int port) {
string data = null;
listener = new TcpListener(IPAddress.Any, port);
listener.Start();
using (var client = listener.AcceptTcpClient()) { // waits until data is avaiable
int MAX = client.ReceiveBufferSize;
var stream = client.GetStream();
Byte[] buffer = new Byte[MAX];
int len = stream.Read(buffer, 0, MAX);
if (0 < len) {
data = Encoding.UTF8.GetString(buffer, 0, len);
}
stream.Close();
client.Close();
}
return data;
}
public static void Send(string message, string host, int port) {
if (!String.IsNullOrEmpty(message)) {
if (port < 80) {
port = DEF_PORT;
}
Byte[] data = Encoding.ASCII.GetBytes(message);
using (var client = new TcpClient(host, port)) {
var stream = client.GetStream();
stream.Write(data, 0, data.Length);
stream.Close();
client.Close();
}
}
}
}
}

c# client/server application only works for lans, fix? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
tcp/ip client server not working over internet
i spent the last week working on a simple windows form application that' s supposed to send a couple of integer numbers from client to server or from server to client. So far i have only managed to make it work for lanns, any idea about how to make it work on the open internet ?
Here' s the code in case you need it (also call me noob but i can' t get how this site handles code, ... does not do what i thought it did so feel free to edit my post in case i fail2format)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace client_server_penta
{
public class Client
{
#region Fields
private int turno = 1;
private TcpClient[] clients = new TcpClient[1]; //used to remember the active client
private int CoordinateX, CoordinateY; //coordinates, they are used by the application
#endregion
public Client(string address)
{
TcpClient client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(address), 3000);
client.Connect(serverEndPoint);
clients[0] = client;
Thread ReadFromServer = new Thread(new ParameterizedThreadStart(this.ReadHandler));
ReadFromServer.Start(client);
}
public void SendData(int a, int b)
{
NetworkStream clientStream = clients[0].GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes(a.ToString() + '$' + b.ToString() + '$');
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
public int ReadCoordinateX()
{
return this.CoordinateX;
}
public int ReadCoordinateY()
{
return this.CoordinateY;
}
private void ReadHandler(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] buffer;
int bytesRead;
while (true)
{
buffer = new byte[10];
bytesRead = 0;
try
{
bytesRead = clientStream.Read(buffer, 0, buffer.Length);
}
catch
{
//an uknown error has occurred
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//data received
ASCIIEncoding encoder = new ASCIIEncoding();
OnDataReceived(encoder.GetString(buffer, 0, buffer.Length));
}
tcpClient.Close();
}
private void OnDataReceived(string text)
{
string first_number = "";
string second_number = "";
int index = 0;
while (text[index] != '$')
first_number += text[index++];
index++;
while (text[index] != '$')
second_number += text[index++];
this.CoordinateX = Convert.ToInt32(first_number);
this.CoordinateY = Convert.ToInt32(second_number);
var myForm = Application.OpenForms["Form2"] as Form2;
myForm.Text = "Turno N." + Convert.ToString(this.turno++);
}
}
}
//and here' s the server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace client_server_penta
{
public class Server
{
private Thread listenThread;
private int turno = 1;
private TcpListener tcpListener;
private TcpClient[] clients = new TcpClient[1]; //used to remember the active client
private int CoordinateX, CoordinateY; //coordinates, they are used by the application
public Server(int port)
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
public void SendData(int a, int b)
{
NetworkStream clientStream = clients[0].GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes(a.ToString()+'$'+b.ToString()+'$');
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
public int ReadCoordinateX()
{
return this.CoordinateX;
}
public int ReadCoordinateY()
{
return this.CoordinateY;
}
private void ListenForClients()
{
this.tcpListener.Start();
TcpClient client = this.tcpListener.AcceptTcpClient();
clients[0] = client;
Thread ReadFromClient = new Thread(new ParameterizedThreadStart(this.ReadHandler));
ReadFromClient.Start(client);
}
private void ReadHandler(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] buffer = new byte[10];
int bytesRead;
while (true)
{
buffer = new byte[10];
bytesRead = 0;
try
{
bytesRead = clientStream.Read(buffer, 0, buffer.Length);
}
catch
{
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//data received
ASCIIEncoding encoder = new ASCIIEncoding();
OnDataReceived(encoder.GetString(buffer, 0, buffer.Length));
}
tcpClient.Close();
}
private void OnDataReceived(string text)
{
string first_number = "";
string second_number = "";
int index = 0;
while (text[index] != '$')
first_number += text[index++];
index++;
while (text[index] != '$')
second_number += text[index++];
this.CoordinateX = Convert.ToInt32(first_number);
this.CoordinateY = Convert.ToInt32(second_number);
var myForm = Application.OpenForms["Form2"] as Form2;
myForm.Text = "Turno N."+Convert.ToString(this.turno++);
}
}
}
Have you opened the 3000 port on your firewall on the two sides ?
Yes of course ^^
If you have routers, don't forget to edit the configurations too.

Categories

Resources