I have established a secure connection to a web server using BouncyCastle TlsClientProtocol and it gave me a System.IO.Stream which I can read and write to, the following code works:
MyTlsSession sess = new MyTlsSession("api.telegram.org", 443);
using (var stream = sess.Stream())
{
var hdr = new StringBuilder();
hdr.AppendLine("GET / HTTP/1.1");
hdr.AppendLine("Host: api.telegram.org");
hdr.AppendLine();
var dataToSend = Encoding.ASCII.GetBytes(hdr.ToString());
stream.Write(dataToSend, 0, dataToSend.Length);
int totalRead = 0;
string response = "";
byte[] buff = new byte[1024];
do
{
totalRead = stream.Read(buff, 0, buff.Length);
response += Encoding.ASCII.GetString(buff, 0, totalRead);
} while (totalRead == buff.Length);
Console.WriteLine(response);
}
How can I instantiate a System.Net.Http.HttpClient on top of this Stream to have a higher-level API instead of dealing with raw bytes?
I don't use built-in TLS capabilities of .NET because of an outdated OS (doesn't have the required cipher suites).
public static string CallTCP(string domainName, int port)
{
try
{
byte[] data = new byte[1024];
string result;
TcpClient client;
Logger.Verbose("CallTCP Connecting", ">>" + domainName);
client = new TcpClient(domainName, port);
NetworkStream ns = client.GetStream();
int recv = ns.Read(data, 0, data.Length);
result = Encoding.ASCII.GetString(data, 0, recv);
Logger.Verbose("CallTCP Connect\t", "<<" + domainName + "->" + result);
ns.Close();
client.Close();
return result;
}
catch (Exception e)
{
Logger.Error("CallTCP", "Error: \t" + e.Message.ToString());
Logger.Error("CallTCP", "Error: \t" + e.StackTrace.ToString());
return null;
}
}
Related
I'm trying to send files from a Socket to another Socket. The sockets are running in two different applications, a client application and a server application. This is happening on the same machine now when testing it. The client first sends to the server when it is ready to receive first info about the file that will be sent to it like filename and file size in bytes in a 2056 bytes message. Then it sends a message each time it is ready to receive a new 2048 buffer of file content.
In short, this is the communication flow for each file:
client -"CLIENT_READY_TO_RECEIVE_FILE_INFO"-------> server
client <-"File name+file size of file coming next"- server
client -"CLIENT_READY_TO_RECEIVE_CONTENT_BUFFER" -> server
client <-"2048 byte buffer of file content"-------- server
...the same flow is repeated until all files are sent to the client.
My problem is that the client receives the file info message wrong, although I have double checked that the server sends it corretly. They both use ASCII encoding. Here is my code:
Client code (receives the files):
private void fetchFilesThreadMethod()
{
String localHostName = Dns.GetHostName();
IPAddress[] localIPs = Dns.GetHostAddresses(localHostName);
IPAddress localIP = localIPs[2];
int port = 1305;
IPEndPoint localEP = new IPEndPoint(localIP,port);
fetchFilesSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
fetchFilesSocket.Bind(localEP);
fetchFilesSocket.Listen(1);
fetchFilesSocket = fetchFilesSocket.Accept();
while (true)
{
byte[] receivedFileInfo = new byte[2056];
byte[] receivedFileCont = new byte[2048];
byte[] comMessage = new byte[100];
byte[] comMessageBytes;
String fileInfoStr = String.Empty;
String fileNameStr = String.Empty; ;
String fileExtStr = String.Empty;
String comMessageStr = String.Empty;
String fileSizeStr = String.Empty;
ulong fileSize = 0;
ulong lastBytesSize = 0;
comMessageStr = "CLIENT_READY_TO_RECEIVE_FILE_INFO";
comMessageBytes = Encoding.ASCII.GetBytes(comMessageStr);
for (int i = 0; i < comMessageBytes.Length; i++)
comMessage[i] = comMessageBytes[i];
Console.WriteLine("Bytes available to be flushed by client: " + fetchFilesSocket.Available);
if (fetchFilesSocket.Available > 0)
{
Console.WriteLine(fetchFilesSocket.Available + " bytes flushed by client.");
byte[] flusher = new byte[fetchFilesSocket.Available];
fetchFilesSocket.Receive(flusher, 0, fetchFilesSocket.Available, SocketFlags.None);
}
fetchFilesSocket.Send(comMessage, 0, 100, SocketFlags.None);
Console.WriteLine("Client sent ready to receive file info.");
fetchFilesSocket.Receive(receivedFileInfo,0,2056, SocketFlags.None);
fileInfoStr = Encoding.ASCII.GetString(receivedFileInfo);
Console.WriteLine("Received file info:" + fileInfoStr);
fileNameStr = fileInfoStr.Split(new String[] { "ENDN" }, StringSplitOptions.None)[0];
Console.WriteLine("Received file name:" + fileNameStr);
fileExtStr = fileNameStr.Split('.').Last();
Console.WriteLine("Received file extension:" + fileExtStr);
fileSizeStr = fileInfoStr.Split(new String[] {"ENDS"},StringSplitOptions.None)[0];
fileSizeStr = fileSizeStr.Split(new String[] {"ENDN"},StringSplitOptions.None).Last();
Console.WriteLine("File size string:" + fileSizeStr);
fileSize = Convert.ToUInt64(fileSizeStr,10);
Console.WriteLine("Received file size:" + fileSize);
lastBytesSize = fileSize % 2048;
ulong byteCount = 0;
bool keepReceiving = true;
ulong buffersReceived = 0;
while (keepReceiving)
{
comMessageStr = "CLIENT_READY_TO_RECEIVE_CONTENT_BUFFER";
comMessageBytes = Encoding.ASCII.GetBytes(comMessageStr);
for (int i = 0; i < comMessageBytes.Length; i++)
comMessage[i] = comMessageBytes[i];
fetchFilesSocket.Send(comMessage, 0, 100, SocketFlags.None);
Console.WriteLine("Console sent ready to receive buffer message.");
if (fileSize - byteCount >= 2048)
{
fetchFilesSocket.Receive(receivedFileCont, 0, 2048, SocketFlags.None);
buffersReceived++;
Console.WriteLine("Buffers received:" + buffersReceived);
byteCount = byteCount + 2048;
}
else
{
fetchFilesSocket.Receive(receivedFileCont, 0, 2048, SocketFlags.None); buffersReceived++;
byteCount = byteCount + 2048;
Console.WriteLine("Buffers received:" + buffersReceived);
keepReceiving = false;
}
Console.WriteLine("Bytes received " + byteCount + "/" + fileSize);
//Console.WriteLine("Received bytes in current file:" + byteCount);
}
Console.WriteLine("File received.");
}
}
Server code (sends the files):
private void fetchThreadMethod(Object commandArgs)
{
if (fetchSocket == null)
{
fetchSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
int port = 1304;
IPEndPoint fetchSocketEP = new IPEndPoint(localIP,port);
fetchSocket.Bind(fetchSocketEP);
}
if (!fetchSocket.Connected)
try
{
fetchSocket.Connect(remoteIP, 1305);
if (fetchSocket.Connected)
Console.WriteLine("Server fetch socket connected.");
}catch(Exception e)
{
Console.WriteLine("Something went wrong when connecting the server fetch socket.");
}
FileCollector fCollector = new FileCollector();
String userName = Environment.GetEnvironmentVariable("USERPROFILE");
String targetDirectory = userName + "\\" + commandArgs;
Console.WriteLine("Path sent to file collector:" + targetDirectory);
fCollector.startFileCollector(targetDirectory);
List<FileNode> collectedFiles = fCollector.getCollectedFiles();
String comMessageStr = String.Empty;
foreach (FileNode fNode in collectedFiles)
{
comMessageStr = String.Empty;
byte[] sentFileInfo = new byte[2056];
byte[] sentFileCont = new byte[2048];
byte[] comMessage = new byte[100];
String fileName = fNode.getFileName();
String formattedFileInfo = fileName;
formattedFileInfo += "ENDN";
ulong fileSize = 0;
FileStream fStream = null;
try
{
fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
FileInfo fInfo = new FileInfo(fileName);
fileSize = (ulong) fInfo.Length;
if (fileSize == 0)
continue;
formattedFileInfo += fileSize.ToString() + "ENDS";
}
catch (Exception e)
{
Console.WriteLine("Could not read from file:" + fileName);
deniedAccessFiles.Add(fileName);
continue;
}
byte[] fileInfoBytes = Encoding.ASCII.GetBytes(formattedFileInfo);
for (int i = 0; i < fileInfoBytes.Length; i++)
sentFileInfo[i] = fileInfoBytes[i];
while (!comMessageStr.Equals("CLIENT_READY_TO_RECEIVE_FILE_INFO"))
{
Console.WriteLine("Server waiting for file info ready message from client.");
fetchSocket.Receive(comMessage,0,100,SocketFlags.None);
comMessageStr = Encoding.ASCII.GetString(comMessage);
comMessageStr = comMessageStr.Substring(0,33);
Console.WriteLine("Received parsed message from client:" + comMessageStr);
}
Console.WriteLine("Server received file info ready message from client.");
comMessageStr = String.Empty;
Console.WriteLine("formattedFileInfo:" + formattedFileInfo);
Console.WriteLine("Sent file info:" + Encoding.ASCII.GetString(sentFileInfo));
fetchSocket.Send(sentFileInfo, 0, 2056, SocketFlags.None);
int readByte = 0;
ulong byteCount = 0;
ulong buffersSent = 0;
while (readByte != -1)
{
if (byteCount == 2048)
{
while (!comMessageStr.Equals("CLIENT_READY_TO_RECEIVE_CONTENT_BUFFER"))
{
Console.WriteLine("Server waiting for ready for buffer message from client.");
fetchSocket.Receive(comMessage, 100, SocketFlags.None);
comMessageStr = Encoding.ASCII.GetString(comMessage);
comMessageStr = comMessageStr.Substring(0,38);
Console.WriteLine("Received parsed message from client 1:" + comMessageStr);
}
Console.WriteLine("Server received ready for buffer message from client.");
fetchSocket.Send(sentFileCont, 0, 2048, SocketFlags.None);
comMessageStr = String.Empty;
buffersSent++;
Console.WriteLine("Buffers sent:" + buffersSent);
byteCount = 0;
}
else
{
readByte = fStream.ReadByte();
if (readByte != -1)
{
sentFileCont[byteCount] = Convert.ToByte(readByte);
byteCount++;
}
}
}
while (!comMessageStr.Equals("CLIENT_READY_TO_RECEIVE_CONTENT_BUFFER"))
{
Console.WriteLine("Server waiting for ready for buffer message from client.");
fetchSocket.Receive(comMessage, 100, SocketFlags.None);
comMessageStr = Encoding.ASCII.GetString(comMessage);
comMessageStr = comMessageStr.Substring(0, 38);
Console.WriteLine("Received parsed message from client 2:" + comMessageStr);
}
Console.WriteLine("Server received ready for buffer message from client.");
fetchSocket.Send(sentFileCont, 0, 2048, SocketFlags.None);
buffersSent++;
Console.WriteLine("Buffers sent:" + buffersSent);
comMessageStr = String.Empty;
}
}
Console outputs:
My recommendation would be to utilise the TCPListener and TCPClient classes provided within System.Net.Sockets they really simplify sending messages over TCP/IP.
Server side you need something like this:
class MyTcpListener
{
public static void Listen()
{
TcpListener server = null;
byte[] bytes = new byte[256];
try
{
// Set the TcpListener on port 13000.
const int port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// 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.
string data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine($"Received: {data}");
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine($"Sent: {data}");
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine($"SocketException: {e}");
}
finally
{
// Stop listening for new clients.
server?.Stop();
}
}
}
Obviously you'll want to adapt it to your program's structure. I took this from here but edited it slightly.
And on your client side you want to use something like this:
class MyTCPClient
{
static void Connect(String server, String message)
{
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.
int port = 13000;
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array. Any encoding can be used as long as it's consistent with the server.
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);
Console.WriteLine($"Sent: {message}");
// Receive the TcpServer.response. This is all optional and can be removed if you aren't recieving a response.
// Buffer to store the response bytes.
data = new byte[256];
// String to store the response ASCII representation.
// Read the first batch of the TcpServer response bytes.
int bytes = stream.Read(data, 0, data.Length);
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {responseData}");
// Close everything.
stream?.Close();
client?.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine($"ArgumentNullException: {e}");
}
catch (SocketException e)
{
Console.WriteLine($"SocketException: {e}");
}
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
}
}
}
Again, this needs to be adapted to your structure and I took it from here. The response stuff can all be removed if you aren't expecting a response from your server.
These two classes are extremely resilient and abstract away all of the complicated stuff, the size of the data buffers can also be changed to whatever size you need.
I am using a c# application that sends data to my server.
I want to send bytes along with the data so that I can handle at server code if the data size is large it can break there only.
I am not getting how to send bytes value along with the data.
The below is my client side sending part and my server side responding part to client.
Client Code :-
public bool sendData(StringBuilder QueryVal)
{
TcpClient clientSocket = new System.Net.Sockets.TcpClient();
try
{
clientSocket.Client.Connect(Serverip, 8888);
var connect = clientSocket.Connected;// it can be ? clientSocket.Client.Connected
if (connect == true)
{
try
{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(QueryVal + "$");
serverStream.Write(outStream, 0, outStream.Length);
String decodedString = System.Text.Encoding.ASCII.GetString(outStream);
decodedData(decodedString.ToString());
serverStream.Flush();
byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
//MessageBox.Show("Receive data is: " + returndata);
int SendByte = outStream.Count();
int ReceivedByte = Convert.ToInt32(returndata);
try
{
clientSocket.Client.Shutdown(SocketShutdown.Both);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
bool chk = clientSocket.Connected;// this line should be comment
if (SendByte == ReceivedByte) { return true; }
else { return false; }
}
catch (Exception ex)
{
StackFrame objtrack = new StackFrame();
var methodinfo = objtrack.GetMethod();
string calssName = methodinfo.DeclaringType.Name;
string methoname = methodinfo.Name;
string Lineno = Convert.ToString(ex.LineNumber());
log(ex.Message, calssName, methoname, Lineno);
return false;
}
}
else
{
return false;
}
}
catch (Exception ex)
{
StackFrame objtrack = new StackFrame();
var methodinfo = objtrack.GetMethod();
string calssName = methodinfo.DeclaringType.Name;
string methoname = methodinfo.Name;
string Lineno = Convert.ToString(ex.LineNumber());
log(ex.Message, calssName, methoname, Lineno);
return false;
}
}
Server Code :-
Byte[] sendBytesAA = Encoding.ASCII.GetBytes(ReceiveSize.ToString());
ReceiveSize = 0;
networkStream.Write(sendBytesAA, 0, sendBytesAA.Length);
Don't convert data to string in can mess up the data and adds unnecessary processing time. Try following code :
TcpClient clientSocket = new TcpClient();
NetworkStream serverStream = clientSocket.GetStream();
List<byte> inStream = new List<byte>();
serverStream.Read(inStream.ToArray(), 0, (int)clientSocket.ReceiveBufferSize);
long length = inStream.Count;
byte[] byteLength = BitConverter.GetBytes(length);
inStream.InsertRange(0, byteLength.ToList());
I have two basic console apps that communicate "over the network" even though all of the communication takes place on my local machine.
Client code:
public static void Main()
{
while (true)
{
try
{
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 500);
Console.WriteLine("Connected.");
byte[] data = ASCIIEncoding.ASCII.GetBytes(new FeederRequest("test", TableType.Event).GetXmlRequest().ToString());
Console.WriteLine("Sending data.....");
using (var stream = client.GetStream())
{
stream.Write(data, 0, data.Length);
stream.Flush();
Console.WriteLine("Data sent.");
}
client.Close();
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
}
Server code:
public static void Main()
{
try
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
Console.WriteLine("Starting TCP listener...");
TcpListener listener = new TcpListener(ipAddress, 500);
listener.Start();
Console.WriteLine("Server is listening on " + listener.LocalEndpoint);
while (true)
{
Socket client = listener.AcceptSocket();
Console.WriteLine("\nConnection accepted.");
var childSocketThread = new Thread(() =>
{
Console.WriteLine("Reading data...\n");
byte[] data = new byte[100];
int size = client.Receive(data);
Console.WriteLine("Recieved data: ");
for (int i = 0; i < size; i++)
Console.Write(Convert.ToChar(data[i]));
//respond to client
Console.WriteLine("\n");
client.Close();
Console.WriteLine("Waiting for a connection...");
});
childSocketThread.Start();
}
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
How can I alter both of these applications so that when the Server has received the data, it responds to the Client with some kind of confirmation?
Thanks in advance!
Here a short example how I would do it:
Server:
class Server
{
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Any, 1500);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
// Create BinaryWriter for writing to stream
BinaryWriter binaryWriter = new BinaryWriter(stream);
// Creating BinaryReader for reading the stream
BinaryReader binaryReader = new BinaryReader(stream);
while (true)
{
// Read incoming information
byte[] data = new byte[16];
int receivedDataLength = binaryReader.Read(data, 0, data.Length);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
// Write incoming information to console
Console.WriteLine("Client: " + stringData);
// Respond to client
byte[] respondData = Encoding.ASCII.GetBytes("respond");
Array.Resize(ref respondData, 16); // Resizing to 16 byte, because in this example all messages have 16 byte to make it easier to understand.
binaryWriter.Write(respondData, 0, 16);
}
}
}
Client:
class Client
{
private static void Main(string[] args)
{
Console.WriteLine("Press any key to start Client");
while (! Console.KeyAvailable)
{
}
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 1500);
NetworkStream networkStream = client.GetStream();
// Create BinaryWriter for writing to stream
BinaryWriter binaryWriter = new BinaryWriter(networkStream);
// Creating BinaryReader for reading the stream
BinaryReader binaryReader = new BinaryReader(networkStream);
// Writing "test" to stream
byte[] writeData = Encoding.ASCII.GetBytes("test");
Array.Resize(ref writeData, 16); // Resizing to 16 byte, because in this example all messages have 16 byte to make it easier to understand.
binaryWriter.Write(writeData, 0, 16);
// Reading response and writing it to console
byte[] responeBytes = new byte[16];
binaryReader.Read(responeBytes, 0, 16);
string response = Encoding.ASCII.GetString(responeBytes);
Console.WriteLine("Server: " + response);
while (true)
{
}
}
}
I hope this helps! ;)
You can perform both Read and Write on the same stream.
After you send all the data over, just call stream.Read as in
using (var stream = client.GetStream())
{
stream.Write(data, 0, data.Length);
stream.Flush();
Console.WriteLine("Data sent.");
stream.Read(....); //added sync read here
}
MSDN documentation on TcpClient has an example as well http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
If you want feed back such as reporting # of bytes received so far, you'll have to use async methods.
Here's an example of what (I think) you want to do:
static void Main(string[] args) {
var server = new Task(Server);
server.Start();
System.Threading.Thread.Sleep(10); // give server thread a chance to setup
try {
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 1500);
Console.WriteLine("Connected.");
var data = new byte[100];
var hello = ASCIIEncoding.ASCII.GetBytes("Hello");
Console.WriteLine("Sending data.....");
using (var stream = client.GetStream()) {
stream.Write(hello, 0, hello.Length);
stream.Flush();
Console.WriteLine("Data sent.");
// You could then read data from server here:
var returned = stream.Read(data, 0, data.Length);
var rec = new String(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length));
rec = rec.TrimEnd('\0');
if (rec == "How are you?") {
var fine = ASCIIEncoding.ASCII.GetBytes("fine and you?");
stream.Write(fine, 0, fine.Length);
}
}
client.Close();
Console.ReadLine();
}
catch (Exception e) {
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
public static void Server() {
try {
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
Console.WriteLine("*Starting TCP listener...");
TcpListener listener = new TcpListener(ipAddress, 1500); // generally use ports > 1024
listener.Start();
Console.WriteLine("*Server is listening on " + listener.LocalEndpoint);
Console.WriteLine("*Waiting for a connection...");
while (true) {
Socket client = listener.AcceptSocket();
while (client.Connected) {
Console.WriteLine("*Connection accepted.");
Console.WriteLine("*Reading data...");
byte[] data = new byte[100];
int size = client.Receive(data);
Console.WriteLine("*Recieved data: ");
var rec = new String(ASCIIEncoding.ASCII.GetChars(data, 0, size));
rec = rec.TrimEnd('\0');
Console.WriteLine(rec);
if (client.Connected == false) {
client.Close();
break;
}
// you would write something back to the client here
if (rec == "Hello") {
client.Send(ASCIIEncoding.ASCII.GetBytes("How are you?"));
}
if (rec == "fine and you?") {
client.Disconnect(false);
}
}
}
listener.Stop();
}
catch (Exception e) {
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
}
Keep in mind that data sent via sockets can arrive fragmented (in different packets). This doesn't usually happen with the packets are small.
I have to trace the HTTP traffic .It work without Https. I try for the https, it successfully get the response via Sslstream through the certificate. When i forward ssl response for the relay but it doesn’t getting the response.
Please let me how to relay SSL response?
Please check the following code for the same.
Thanks
public void ThreadHandleHTTPClient(object o)
{
try{
Socket client = (Socket)o;
Stream ns = new NetworkStream(client);
//Stream outStrem = ns;
//RECEIVE CLIENT DATA
byte[] buffer = new byte[2048];
int rec = 0, sent = 0, transferred = 0, rport = 0;
string data = "";
do
{
rec = ns.Read(buffer, 0, buffer.Length);
data += Encoding.ASCII.GetString(buffer, 0, rec);
} while (rec == buffer.Length);
//PARSE DESTINATION AND SEND REQUEST
string line = data.Replace("\r\n", "\n").Split(new string[] { "\n" }, StringSplitOptions.None)[0];
string e=line.Split(new string[] { " " }, StringSplitOptions.None)[1];
Uri uri = new Uri(e);
if (uri.Scheme == "https" || line.Contains("CONNECT"))
{
rport = 443;
//Make tunnel for the HTTPS which is authentic host.
SslStream sslStream = sslTunnel(ns, uri.OriginalString, "1.0");
ns = sslStream;
string remoteUri = "https://" + uri.Scheme;
StreamReader clientStreamReader = new StreamReader(sslStream);
string httpCmd = clientStreamReader.ReadLine();
string[] splitBuffer = httpCmd.Split(_spaceSplit, 3);
remoteUri = remoteUri + splitBuffer[1];
myQuery = string.Empty;
//Read the SSL Stream save command in myQuery variable.
readRequestHeadersEx(clientStreamReader);
data = myQuery;
data = splitBuffer[0]+" ";
data += remoteUri;
data += " ";
data += splitBuffer[2];
data += "\r\n";
data += myQuery;
data += "\r\n";
line = data.Replace("\r\n", "\n").Split(new string[] { "\n" }, StringSplitOptions.None)[0];
uri = new Uri(line.Split(new string[] { " " }, StringSplitOptions.None)[1]);
}
else
{
rport = 80;
}
IPHostEntry rh = Dns.GetHostEntry(uri.Host);
Socket remoteserver = new Socket(rh.AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.IP);
remoteserver.Connect(new IPEndPoint(rh.AddressList[0], rport));
byte[] databytes = Encoding.ASCII.GetBytes(data);
remoteserver.Send(databytes, databytes.Length, SocketFlags.None);
//START RELAY
buffer = new byte[2048];
rec = 0;
data = "";
do
{
transferred = 0;
do
{
rec = remoteserver.Receive(buffer, buffer.Length, SocketFlags.None);
sent = client.Send(buffer, rec, SocketFlags.None);
transferred += rec;
data += Encoding.ASCII.GetString(buffer, 0, rec);
} while (rec == buffer.Length);
if (transferred == 0)
break;
} while (transferred > 0);
client.Close();
}
catch (Exception ex)
{
}
}
public void Start(IPAddress ip, int port)
{
TcpListener listener = new TcpListener(ip, port);
listener.Start(100);
while (true)
{
Socket client = listener.AcceptSocket();
Thread th = new Thread(ThreadHandleHTTPClient);
th.Start(client);
}
listener.Stop();
}
In C# to test if UltraVNC was up and running on a local machine I would do this
public static bool TestAvailablility(int port, string responseStartsWith)
{
bool toReturn = false;
try
{
using (TcpClient client1 = new TcpClient())
{
client1.ReceiveTimeout = 10000;
client1.SendTimeout = 10000;
client1.Connect("localhost", port);
using (NetworkStream stream = client1.GetStream())
{
Byte[] response = new Byte[4096];
Int32 bytes = 0;
string serverReturnString = null;
bytes = stream.Read(response, 0, response.Length);
serverReturnString = System.Text.Encoding.ASCII.GetString(response, 0, bytes);
Console.WriteLine("TestAvailablility: serverReturnString = {0}", serverReturnString);
if (serverReturnString.StartsWith(responseStartsWith, StringComparison.OrdinalIgnoreCase))
{
toReturn = true;
}
}
}
}
catch (Exception ex) // SocketException for connect, IOException for the read.
{
Console.WriteLine("TestAvailable - Could not connect to VNC server. Exception info: ", ex);
}
return toReturn;
}
I'm new to Java so I'm hoping someone can help me with an equivalent method to preform this action.
Here's what I came up with:
FYI using Autocomplete in Eclipse + Java API you can translate C# to Java pretty easily.
public static boolean testAvailablility(int port, String responseStartsWith) {
boolean toReturn = false;
try {
Socket client1 = new Socket();
client1.setSoTimeout(10000);
client1.bind(new InetSocketAddress("localhost", port));
InputStream stream = client1.getInputStream();
byte[] response = new byte[4096];
int bytes = 0;
String serverReturnString = null;
bytes = stream.read(response, 0, response.length);
serverReturnString = String.valueOf(bytes);
System.out.println("TestAvailablility: serverReturnString = {0} " + serverReturnString);
if (serverReturnString.toLowerCase().startsWith(responseStartsWith.toLowerCase()))
toReturn = true;
} catch (Exception ex) // SocketException for connect, IOException for
// the read.
{
System.out.println("TestAvailable - Could not connect to VNC server. Exception info: ");
ex.printStackTrace();
}
return toReturn;
}