I am using TcpClient to connect to a socket, below is the sample code, which I connect to the socket once to retain conenction session id, then I keep on transmitting and receiving message from the socket, until I found a valid message, then I stop:
// client is a global object to retain connection session id
TcpClient client = new TcpClient("127.0.0.1", 1800);
public void Connect()
{
message = "First message"; // first message
do
{
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
data = new Byte[256];
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
} while (message = "valid") // loop untill message is valid
stream.Close();
client.Close();
}
My question is how can I use the TcpClient.ReceiveTimeout and TcpClient.SentTimeout 20 seconds effectively in my code?
Am I doing the right thing with the TcpClient connection to retain the connection session id?
Thank you.
Related
I have a TCP Client
Log.Warn("Trying to connect to " + IP);
TcpClient client = new TcpClient(IP, Port);
string command = "";
while (!command.Contains("quit"))
{
Log.WriteSingle("localhost#", ConsoleColor.DarkYellow);
Log.WriteSingle(IP + ":", ConsoleColor.Yellow);
command = Console.ReadLine();
byte[] data = Encoding.ASCII.GetBytes(command);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Log.Success("Sent command to network.");
// 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);
Log.Write("Server Says: " + responseData, ConsoleColor.DarkYellow);
}
and a TCP Server
while(true)
{
Log.Write("Waiting for connection...");
TcpClient client = server.AcceptTcpClient();
Log.Success("Connected! ");
//Update list (Currently useless)
clientList.Add(client);
Thread t = new Thread(new ThreadStart(()=>ConnectClient(client,bytes,data)));
t.Start();
}
public static void ConnectClient(TcpClient _client, byte[] _bytes, string _data)
{
_data = null;
NetworkStream stream = _client.GetStream();
int i;
while((i = stream.Read(_bytes,0,_bytes.Length))!=0)
{
_data = System.Text.Encoding.ASCII.GetString(_bytes,0,i);
Log.Write("Recieved: "+_data, ConsoleColor.Cyan);
//Send back to client
_data = _data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(_data);
stream.Write(msg,0,msg.Length);
Log.Write("Sent: "+_data);
}
_client.Close();
}
I have it setup so the server listens to client connections and pop them off in a new thread once they connect. The client can send the server a string, and the server reflects it back.
I assume I can use a dictionary to assign an ID and store the client, or even just a simple List.
How would I structure it so I can add them to a List or a Dictionary and still be able to connect multiple clients?
Thanks
Put your accept() loop in a thread of its own. It can add to the list each time a new client connects.
Leave your main thread to manage all the client threads, including the accept() thread.
I've been creating a TCPClient which is suppose to connect to a server but am getting this error:
System.InvalidOperationException: 'The operation is not allowed on
non-connected sockets.'
Here's my Code:
Public String IPAddress = "192.168.100.xxx"
Public Int32 Port = 23;
public TcpClient client = new TcpClient();
public void Connect() {
client.Connect(IPAddress, Port);
// send first message request to server
Byte[] msg_data = System.Text.Encoding.ASCII.GetBytes("Hello Server);
// uses the GetStream public method to return the NetworkStream
NetworkStream netStream = _client.GetStream();
// write message to the network
netStream.Write(msg_data, 0, msg_data.Length);
// buffer to store the response bytes
msg_data = new Byte[256];
// read the first batch of response byte from arduino server
Int32 bytes = netStream.Read(msg_data, 0, msg_data.Length);
received_msg = System.Text.Encoding.ASCII.GetString(msg_data, 0, bytes);
netStream.Close();
}
public void Send() {
// message data byes to be sent to server
Byte[] msg_data = System.Text.Encoding.ASCII.GetBytes(_sendMessage);
// uses the GetStream public method to return the NetworkStream
// ** Error Here: System.InvalidOperationException: 'The operation is not allowed on non-connected sockets.'
NetworkStream netStream = client.GetStream();
// write message to the network
netStream.Write(msg_data, 0, msg_data.Length);
// buffer to store the response bytes
msg_data = new Byte[256];
// read the first batch of response byte from arduino server
Int32 bytes = netStream.Read(msg_data, 0, msg_data.Length);
received_msg = System.Text.Encoding.ASCII.GetString(msg_data, 0, bytes);
netStream.Close(); // close Stream
}
I am getting and error when creating a new instance of NetworkStream netStream = client.GetStream();. Been struggling to find whats causing the error, I think it's somehow closing the connection above.
Everything is in a class and must be called at anyplace in the software.
client.GetStream() is implemented like:
return new NetworkStream(this.Client, true);
whereas the true means if the stream is disposed/closed it also closes/disconnects the socket/client. You should be able to avoid this by directly calling
var netStream = new NetworkStream(client.Client, false);
And even better would be instead of:
NetworkStream netStream = client.GetStream();
…
netSteam.Dlose();
to ensure that the stream is always closed even if an errors by writing:
using (var netStream = new NetworkStream(client.Client, false))
{
…
}
i've wrote a simple Tcp server in C#:
(I've replaced some of the code parts in "do some stuff", when it doesn't have anything to do with the server.
now, when I try to contact the server from a python client, or an android client, I get errors such as : "the other party actively refused connection". what am I supposed to do? is the problem in my C# code, or am I probably not contacting it correctly?
thank you.
public bool ListenLoop(Int32 port, IPAddress localAddr)
{
try
{
server = new TcpListener(localAddr, port);
// 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)
{
//Waiting for a connection
// Perform a blocking call to accept requests.
TcpClient client = server.AcceptTcpClient();
//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.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
//handling opCodes
if(data[0] == '0') //log in
{
//do some stuff
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
stream.Write(msg, 0, msg.Length);
//sent
}
else if (data[0] == '1') //download tune names
{
//do some stuff
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response); //response is the names
// Send back a response.
stream.Write(msg, 0, msg.Length);
//sent
}
else if (data[0] == '2') //changing choice
{
//do some stuff
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
stream.Write(msg, 0, msg.Length);
//sent
}
}
// Shutdown and end connection
client.Close();
}
}
catch(SocketException)
{
return false;
}
finally
{
// Stop listening for new clients.
server.Stop();
}
}
Are you sure that there is no firewall that blocks the incoming connection (as it is TCP)?
Also if your server is in testing, you should write some output to either a log file or even just to console. At least you know what is going on.
server = new TcpListener(localAddr, port);
change to
server = new TcpListener(port);
I want to receive message on C# client from Netty server. I use sync C# socket and protobuf.
I send message to server and it's ok. But I can't receive response.
Netty server uses ProtobufDecoder. Server ChannelInboundHandler has this part of code:
public void channelRead0(final ChannelHandlerContext ctx, Object msg) {
...
Set<String> keys = jedis.keys("tanks*");
String allKeys = "";
for(String key: keys){
allKeys+=key+";";
}
ctx.write(allKeys);
ctx.flush();
}
C# client code is:
const string server = "localhost";
const int port = 8080;
var tcpClient = new TcpClient(server, port);
_networkStream = tcpClient.GetStream();
var stream = new MemoryStream();
Serializer.Serialize(stream, tankDataObject);
var data = stream.ToArray();
_networkStream.Write(data, 0, data.Length);
data = new Byte[10000];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = _networkStream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
// Close everything.
_networkStream.Close();
tcpClient.Close();
Client doesn't receive any bytes or receive empty array if I call ctx.close() on server. Any help will be appreciated. Thank you.
I am trying to connect with a robot controller from PC using TCP/IP. The robot controller accepts only the ASCII string data from the PC (TCP Client). According to the Robot controller's command structure I have to send a particular string and get ACK from it to get the access.
I used the following code
try
{
System.Net.IPAddress IPADD = System.Net.IPAddress.Parse("192.168.255.2");
int PortNo = 80;
char[] ok = new char[33];
byte[] Data = new byte[33];
byte[] StartReq = new byte[21];
String Start = "CONNECT Robot_access";
// INITIALIZING TCP CLIENT
TcpClient TCP = new TcpClient();
Console.WriteLine("Connecting..........");
TCP.Connect(IPADD, PortNo);
Console.WriteLine("Connected");
NetworkStream NS = TCP.GetStream();
// START REQUEST
StartReq = Encoding.ASCII.GetBytes(Start);
NS.Write(StartReq, 0, StartReq.Length);
Console.WriteLine("start request send..........");
// RECEIVE ACK FOR ROBOT ACCESS
Int32 RespData = NS.Read(Data, 0, Data.Length);
string ACK = Encoding.ASCII.GetString(Data, 0, RespData);
Console.WriteLine("The ACK is {0} ", ACK);
Console.WriteLine("ACK Received");
Console.Read();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.Read();
}
I have aslo tried Streamwriter and Bufferstream to send and receive string couldn't succeed. My program runs through completely without any exception (except a 30s delay for Networkstream reading).