How to use Tor control protocol in C#? - c#

I'm trying to send commands to the Tor control port programmatically to make it refresh the chain. I haven't been able to find any examples in C#, and my solution's not working. The request times out. I have the service running, and I can see it listening on the control port.
public string Refresh()
{
TcpClient client = new TcpClient("localhost", 9051);
string response = string.Empty;
string authenticate = MakeTcpRequest("AUTHENTICATE\r\n", client);
if (authenticate.Equals("250"))
{
response = MakeTcpRequest("SIGNAL NEWNYM\r\n", client);
}
client.Close();
return response;
}
public string MakeTcpRequest(string message, TcpClient client)
{
client.ReceiveTimeout = 20000;
client.SendTimeout = 20000;
string proxyResponse = string.Empty;
try
{
// Send message
StreamWriter streamWriter = new StreamWriter(client.GetStream());
streamWriter.Write(message);
streamWriter.Flush();
// Read response
StreamReader streamReader = new StreamReader(client.GetStream());
proxyResponse = streamReader.ReadToEnd();
}
catch (Exception ex)
{
// Ignore
}
return proxyResponse;
}
Can anyone spot what I'm doing wrong?
Edit:
Following Hans's suggestion, which he has now deleted for some reason, I tried to send "AUTHENTICATE\n" instead of just "AUTHENTICATE". Now I'm getting back an error from Tor: "551 Invalid quoted string. You need to put the password in double quotes." At least there's some progress.
I then tried to send "AUTHENTICATE \"\"\n", like it wants to, but it times out while waiting for a response.
Edit:
The command works fine in the Windows Telnet client. I don't even have to add the quotes. Can't figure out what's wrong. Maybe the double quotes aren't encoded correctly when they're sent?

public static void CheckIfBlocked(ref HtmlDocument htmlDoc, string ypURL, HtmlWeb hw)
{
if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
{
Console.WriteLine("Getting Blocked");
Utils.RefreshTor();
htmlDoc = hw.Load(ypURL, "127.0.0.1", 8118, null, null);
if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
{
Console.WriteLine("Getting Blocked");
Utils.RefreshTor();
}
}
}
public static void RefreshTor()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9051);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
server.Connect(ip);
}
catch (SocketException e)
{
Console.WriteLine("Unable to connect to server.");
RefreshTor();
return;
}
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"butt\"\n"));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (stringData.Contains("250"))
{
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM\r\n"));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
Console.WriteLine("Unable to signal new user to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
RefreshTor();
}
}
else
{
Console.WriteLine("Unable to authenticate to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
RefreshTor();
}
server.Shutdown(SocketShutdown.Both);
server.Close();
}

When I send the AUTHENTICATE command, the StreamReader is reading the response to the end, but there is no end because on success the stream is kept open. So I changed it to only read the first line of the response in this case.
public static string MakeTcpRequest(string message, TcpClient client, bool readToEnd)
{
client.ReceiveTimeout = 20000;
client.SendTimeout = 20000;
string proxyResponse = string.Empty;
try
{
// Send message
using (StreamWriter streamWriter = new StreamWriter(client.GetStream()))
{
streamWriter.Write(message);
streamWriter.Flush();
}
// Read response
using (StreamReader streamReader = new StreamReader(client.GetStream()))
{
proxyResponse = readToEnd ? streamReader.ReadToEnd() : streamReader.ReadLine();
}
}
catch (Exception ex)
{
throw ex;
}
return proxyResponse;
}

Added another example I'm using myself below. Also added steps for those who would like to setup Tor that can accept commands through the control port.
Socket server = null;
//Authenticate using control password
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9151);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Connect(endPoint);
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"your_password\"" + Environment.NewLine));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
//Request a new Identity
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM" + Environment.NewLine));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
Console.WriteLine("Unable to signal new user to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
}
else
{
Console.WriteLine("SIGNAL NEWNYM sent successfully");
}
Steps to configure Tor:
Copy torrc-defaults into the directory in which tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Data\Tor"
Open a cmd prompt window
chdir to the directory where tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Tor\"
Generate a password for Tor control port access. tor.exe --hash-password “your_password_without_hyphens” | more
Add your password password hash to torrc-defaults under ControlPort 9151. It should look something like this: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. If you accept your password to be "password" you can copy the string above.
You can now access Tor control via Telnet once it is started. Now the code can run, just edit the path to where your Tor files are located in the program.
Test modifying Tor via Telnet:
Start tor with the following command: tor.exe -f .\torrc-defaults
Open up another cmd prompt and type: telnet localhost 9151
If all goes well you should see a completely black screen. Type "autenticate “your_password_with_hyphens”" If all goes well you should see "250 OK".
Type "SIGNAL NEWNYM" and you will get a new route, ergo new IP. If all goes well you should see "250 OK".
Type "setevents circ" (circuit events) to enable console output
Type "getinfo circuit-status" to see current circuits

Probably you using Vidalia that generates a hashed password for control port access. You need to use Tor console app and configure a torrc file.

Related

TcpClient does not read response from the server (.Net core)

I am currently working on a network project that needs to send a request to the server and gets a response from it. The server is hosted by the third party company so I don't have direct access to the server but I can request server logs. According to that logs, my request was successfully sent to the server and the server also replies with the response. But the response doesn't receive to my side. I also used Packet Sender Tool to check the response and it also didn't receive any response. What could be the issue here? There is nothing wrong with my code because I receive responses when I connect to different servers. this problem only occurs with one specific server. Thanks all.
//establish TcpConnection
public async Task<TcpClient> ConnectAsync(TcpClient tcpClient)
{
string xmlMessageServer = _configuration["XmlMessageStrings:xmlMessageServer"];
string xmlMessagePort = _configuration["XmlMessageStrings:xmlMessagePort"];
var errorLog = NLogBuilder.ConfigureNLog("NLog.config").GetLogger("debitcardErrorLog");
try
{
await tcpClient.ConnectAsync(xmlMessageServer, Convert.ToInt32(xmlMessagePort));
errorLog.Info(tcpClient.GetHashCode());
return tcpClient;
}
catch (SocketException ex)
{
errorLog.Error(ex.Message); // log error
throw ex;
}
}
try
{
TcpClient tcpClient = new TcpClient();
await _connectWithTcpServer.ConnectAsync(tcpClient);
if (tcpClient.Connected)
{
debitcardRequestLog.Info("Tcp Client Connected"); // check if client connected
NetworkStream stream = tcpClient.GetStream();
debitcardRequestLog.Info(xmlMessage); // log xmlMessage
byte[] xmlRequest = Encoding.ASCII.GetBytes(xmlMessage); // converts the xmlRequest into a byte array
stream.Write(xmlRequest, 0, xmlRequest.Length); //writes the xmlRequest into the stream
byte[] bufferSize = new byte[tcpClient.ReceiveBufferSize]; //converts the bufferSize into a byte array
int xmlResponse = stream.Read(bufferSize, 0, bufferSize.Length); //reads the xml response from switchware
if (xmlResponse == 0)
{
errorLog.Error("0 bytes received from server");
}
string xmlResponseMsg = string.Empty;
string xmlResponseMsgASCII = Encoding.ASCII.GetString(bufferSize, 0, 0); // decode the byte array into a string
debitcardResponseLog.Info(xmlResponseMsgASCII);
fromSwitchwareMessage = xmlResponseMsgASCII;
}
}
catch (Exception ex)
{
errorLog.Error(ex.Message); // log error
throw ex;
}

How I can to create python(or swift) TCP client for my TCP c# server?

How I can to create python(or swift) TCP client for my TCP c# server?
c# API for my TCP server:
Client client = Client();
bool Connect()
{
UserInfo userInfo = new UserInfo("login", "pass");
NetworkConnectionParam connectionParams = new NetworkConnectionParam("127.0.0.1", 4021);
try
{
client.Connect(connectionParams,userInfo,ClientInitFlags.Empty);
}
catch
{
return false;
}
return client.IsStarted;
}
I try it(python) :
import socket
sock = socket.socket()
sock.connect(('localhost', 4021))
But I don't uderstand how I must to send my login and password (like in API for c#).
I don`t undestand what you want to implement.
If you want to run Python code in C#, then look at this IronPython
If you want to implement TCP client in C#, then try smth like this:
using System.Net;
using System.Net.Sockets;
class Program
{
static int port = 8005; // your port
static void Main(string[] args)
{
// get address to run socket
var ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
// create socket
var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
// binding
listenSocket.Bind(ipPoint);
// start listen
listenSocket.Listen(10);
Console.WriteLine("Server is working");
while (true)
{
Socket handler = listenSocket.Accept();
// recieve message
StringBuilder builder = new StringBuilder();
int bytes = 0; // quantity of received bytes
byte[] data = new byte[256]; // data buffer
do
{
bytes = handler.Receive(data);
builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
}
while (handler.Available>0);
Console.WriteLine(DateTime.Now.ToShortTimeString() + ": " + builder.ToString());
// send response
string message = "your message recieved";
data = Encoding.Unicode.GetBytes(message);
handler.Send(data);
// close socket
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

Proxy server does not load images

I'm trying to make a proxy server with C#.
Here's my code:
static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 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();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
WebRequest request;
WebResponse response;
// 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!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
String[] input;
// Loop to receive all the data sent by the client.
while (stream.DataAvailable)
{
data = null;
i = stream.Read(bytes, 0, bytes.Length);
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
input = data.Split();
Console.WriteLine("\n\r\n input[1]" + input[1] + "\n");
Stream dataStream;
StreamReader reader;
string responseFromServer;
try
{
request = WebRequest.Create(input[1]);
response = request.GetResponse();
// Process the data sent by the client.
data = data.ToUpper();
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(dataStream);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Display the content
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
byte[] msg = System.Text.Encoding.ASCII.GetBytes(responseFromServer);
// Send back a response.
stream.Write(msg, 0, msg.Length);
// Console.WriteLine("Sent: {0}", data);
//stream.Write();
reader.Close();
response.Close();
}
catch (System.UriFormatException e)
{
Console.WriteLine("Exception due to" + e.Data);
Console.WriteLine("Input[1] = " + input[1]);
}
data = null;
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
It does not work for ssl requests but seems to work for http.
However, it does not load any images.
I'm using Firefox as the browser.
Any ideas why?
Also is this the best way to make a proxy server? Are there any other methods?
After a bit of testing, I wrote my own code.
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Text;
namespace SharpProxy
{
class MainClass
{
private static void StartAcceptingClient(IAsyncResult ar)
{
var tcpClient = server.EndAcceptTcpClient(ar);
server.BeginAcceptTcpClient(new AsyncCallback(StartAcceptingClient), null);
// Read the data stream from the client.
NetworkStream stream = tcpClient.GetStream();
byte[] buffer = new byte[256];
Console.WriteLine("====== GOT A NEW TCP CLIENT ====== " + tcpClient.Client.RemoteEndPoint.ToString());
int read = stream.Read(buffer, 0, 1);
MemoryStream saved = new MemoryStream();
saved.Write(buffer, 0, read);
bool isValid = false;
while (read > 0 )
{
read = stream.Read(buffer, 0, 1);
saved.Write(buffer, 0, read);
//Check if the last four bytes were a double \r\n.
var aBytes = saved.ToArray();
int len = aBytes.Length;
if (aBytes.Length >= 4 && aBytes[len - 1] == '\n' && aBytes[len - 2] == '\r' && aBytes[len - 3] == '\n' && aBytes[len - 4] == '\r')
{
isValid = true;
break;
}
}
Console.WriteLine("End of receive.");
string originalRequest = Encoding.ASCII.GetString(saved.ToArray());
byte[] origBytes = saved.ToArray();
saved.Close();
Console.WriteLine(originalRequest);
if (!isValid)
{
Console.WriteLine("This wasn't a valid request");
return;
}
//Find the hoster and do our own request.
string host = originalRequest.Split(new char[] { '\n' }).First(line => line.StartsWith("Host:"));
host = host.Substring(5).Trim(); //Cut of rest.
Console.WriteLine("The host is: " + host);
//Do our own request.
try
{
Socket sProxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sProxy.Connect(host, 80);
sProxy.Send(origBytes);
//Now route everything between the tcpclient and this socket...
//create the state object
var state = new ProxyState() { ourSocket = sProxy, incomingClient = stream };
sProxy.BeginReceive(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(Receiver), state);
stream.BeginRead(state.SendBuffer, 0, state.SendBuffer.Length, new AsyncCallback(SendToHTTPServer), state);
}
catch (Exception) { Console.WriteLine("Exception while doing our own request"); }
}
static TcpListener server = null;
public static void Main(string[] args)
{
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("0.0.0.0");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
Console.WriteLine("Server started on " + server.LocalEndpoint.ToString());
server.BeginAcceptTcpClient(new AsyncCallback(StartAcceptingClient), null);
while (true)
Thread.Sleep(10);
}
catch (Exception) { Console.WriteLine("Setting up the server failed"); }
}
private static void SendToHTTPServer(IAsyncResult ar)
{
try
{
ProxyState back = (ProxyState)ar.AsyncState;
int rec = back.incomingClient.EndRead(ar);
//Push this content to the server
back.ourSocket.Send(back.SendBuffer.Take(rec).ToArray());
back.incomingClient.BeginRead(back.SendBuffer, 0, back.SendBuffer.Length, new AsyncCallback(SendToHTTPServer), back);
}
catch (Exception e) { Console.WriteLine("Exc. when sending to server: " + e.ToString()); }
}
static void Receiver(IAsyncResult state)
{
try
{
ProxyState back = (ProxyState)state.AsyncState;
int rec = back.ourSocket.EndReceive(state);
//Set up the back and forth connections
back.incomingClient.Write(back.ReceiveBuffer, 0, rec);
back.ourSocket.BeginReceive(back.ReceiveBuffer, 0, back.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(Receiver), back);
}
catch (Exception e) { Console.WriteLine("Exc. when receiving from client: " + e.ToString()); }
}
//Every proxy connection has an end an and a beginning, plus a
//Sending buffer and a receive buffer
class ProxyState
{
public NetworkStream incomingClient { get; set; }
public Socket ourSocket { get; set; }
private byte[] buffReceive = new byte[512];
private byte[] buffSend = new byte[512];
public byte[] ReceiveBuffer { get { return buffReceive; } set { buffReceive = value; } }
public byte[] SendBuffer { get { return buffSend; } set { buffSend = value; } }
}
}
}
Here's how it works: I listen on a port, and wait for a HTTP request. This is ended by a double carriage return and a linefeed, a \r\n\r\n. As soon as that happens, I try to parse the original host from the request with a Linq statement. I open my own socket to the server, and make use of the asynchronous callbacks. Basically, you need to write everything that comes from the proxy-iniator to the HTTP-Server, and everything that the HTTP-Server sends back needs to be pushed back to the original client aswell. This is why I set up my own state-object, which just saves the incomming client and the Socket, which is connected to the original HTTP server. And as such, communication can happen and I act as a proxy server.
Here's a screenshot with all the connections done right:
This proxy server is far from perfect, but the basic concept should be clear. This gave me some inspiration.
You use a streamreader on binary image data, that is not going to work. Not every binary is a valid ASCII encoded string. You should read the response as binary, and write it to the other stream as binary as well. You can try to convert it to ascii to print it to the console, but do not use the converted text to respond, because all the non-valid ascii characters will be converted to ?-s. I did modify your code to first read the response in a MemoryStream, and write that back. The data written to the console is still converted, but not user anywhere else.
static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 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();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
WebRequest request;
WebResponse response;
// 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!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
String[] input;
// Loop to receive all the data sent by the client.
while (stream.DataAvailable)
{
data = null;
i = stream.Read(bytes, 0, bytes.Length);
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
input = data.Split();
Console.WriteLine("\n\r\n input[1]" + input[1] + "\n");
Stream dataStream;
StreamReader reader;
string responseFromServer;
try
{
request = WebRequest.Create(input[1]);
response = request.GetResponse();
// Process the data sent by the client.
data = data.ToUpper();
dataStream = response.GetResponseStream();
MemoryStream ms = new MemoryStream();
dataStream.CopyTo(ms);
ms.Position = 0;
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(ms);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Display the content
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
byte[] msg = ms.ToArray();
// Send back a response.
stream.Write(msg, 0, msg.Length);
// Console.WriteLine("Sent: {0}", data);
//stream.Write();
reader.Close();
response.Close();
}
catch (System.UriFormatException e)
{
Console.WriteLine("Exception due to" + e.Data);
Console.WriteLine("Input[1] = " + input[1]);
}
data = null;
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}

C# client communication Via UPD

I am looking for some help with communication between my server application and my client.The idea is that my client will listen for a UDP packet, read it and then execute a command based on what it reads.
My issue is that the server sends the packet however the client does nothing.
Here is a snippet of my code:
Client:
public void listen()
{
try
{
MessageBox.Show("");
UdpClient receivingUdpClient = new UdpClient(11000);
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 11000);
try
{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.ASCII.GetString(receiveBytes);
string[] split = returnData.Split(':');
if (split[0] == "SayHello")
{
MessageBox.show("Hello user","Hello");
}
//Note i have many commands but i shortened it to save room.
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Server:
else if (radioButton4.Checked)
{
UdpClient udpClient = new UdpClient([IP_ADDRESS_HERE], 11000);
body = richTextBox1.Text;
title = textBox1.Text;
Command = "Message" + ":" + body + ":" + title + ":" + 4;
Byte[] sendBytes = Encoding.ASCII.GetBytes(Command);
try
{
udpClient.Send(sendBytes, sendBytes.Length);
}
catch (Exception)
{
Console.WriteLine(e.ToString());
}
}
Just wanted to see if you guys are able to find something I overlooked.
Check your Windows Firewall and verify it's not blocking your Client from opening port 11000.
Control Panel-> System and Security -> Windows Firewall

Java <-> C# Socket: cant receive messages

I need a socket communication between my own written java server and C# client, the problem is that the C# client can't receive any messages from my java server, but sending messages to my java server works.
my workflow:
Java: Create Server
Java: Waiting for Client connection
c#: Create Client
c#: Build connection to the server
c#: send a msg to the server
Java: msg received
java: send msg to c# client
c#: receiving msg from server <- this is the point where the client waits for a message but never get.
Java Server code:
public class Communicator {
private int m_port;
private Socket m_socket;
private ServerSocket m_serverSocket;
public Communicator(int port) {
this.m_port = port;
initConnection();
}
private void initConnection() {
try {
System.out.println("Creating Server");
m_serverSocket = new ServerSocket(m_port);
System.out.println("Waiting for client connection");
m_socket = m_serverSocket.accept();
System.out.println("Connection made");
} catch (IOException e) {
e.printStackTrace();
}
}
public String sendMsg(JSONMessage msg) {
try {
//get msg
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(m_socket.getInputStream()));
System.out.println("Waiting for msg...");
String answer = bufferedReader.readLine();
System.out.println("Received: " + answer);
//send msg
PrintWriter writer = new PrintWriter(m_socket.getOutputStream(),true);
writer.print(msg.getMsg());
System.out.println("Sending: " + msg.getMsg());
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
My C# client code:
class Communicator
{
private int m_port;
private Thread mainThread;
public Communicator(int port)
{
m_port = port;
mainThread = new Thread(new ThreadStart(this.initConnection));
mainThread.Start();
}
public void initConnection()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), m_port);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
Console.WriteLine("Trying to build connection");
server.Connect(ip);
Console.WriteLine("Connection successful");
NetworkStream ns = new NetworkStream(server);
StreamReader sr = new StreamReader(ns);
StreamWriter sw = new StreamWriter(ns);
string data;
string welcome = "Hello";
Console.WriteLine("Sending: " + welcome);
sw.WriteLine(welcome);
sw.Flush();
Console.WriteLine("Receiving...");
data = sr.ReadLine();
// --> NEVER REACHING THIS POINT <---
Console.WriteLine("Received: " + data);
}
catch (SocketException e)
{
Console.WriteLine("Connection failed.");
return;
}
}
}
Does somebody has any idea why it never reaches my client code Console.WriteLine("Received: " + data); ?
I already tried with waits on both sides. I'm not getting any exceptions or error so I don't have really an idea where my problem is.
Thanks
If your receiver is expecting lines, your sender has to send lines. Your sender does not send lines, so the receiver waits forever until it gets one.
To avoid these kinds of problems in the future, you should always make a specification document that explains how your protocol works, ideally at the byte level. It should specify whether the protocol contains messages and if so, how the sender marks message boundaries and how the receiver identifies them.
Here, your receiver identifies message boundaries by looking for line endings. But your sender doesn't mark message boundaries with line endings. So the receiver waits forever.
If you had a protocol specification, this would have been obvious. In the future, I strongly urge you to invest the time to specify every protocol you implement.
You need to use println() which adds a new line instead of print(). In Java, readLine waits for a new line and I would expect it to do the same in C#. Also println will auto-flush, so you don't need to flush as well.
If you intend to use this connection mreo than once, you need to keep the BufferedReader and PrintWriter for the connection. (So I suggest you create these after the socket is created/accepted) Creating these multiple times for the same socket can be error prone and confusing.

Categories