I've been looking around for the answer without luck. The program is a simple chat app that either listens or talks. The connection is established between the client and server, but when I send a message, the other does not seem to recieve it.
server waiting for connection
private void ListenForConnection(IPAddress ipAddress)
{
tcpListener = new TcpListener(ipAddress, portNumber);
tcpListener.Start();
client = tcpListener.AcceptTcpClient();
stream = client.GetStream();
stream.ReadTimeout = 200;
}
client connecting
private void EstablishConnection(IPAddress ipAddress)
{
client = new TcpClient();
client.Connect(ipAddress, portNumber);
stream = client.GetStream();
stream.ReadTimeout = 200;
}
client writing a message
public void SendMessage(String message)
{
StreamWriter networkWriter = new StreamWriter(stream);
networkWriter.Write(message);
networkWriter.Flush();
}
server reading a message
public String ListenForMessage()
{
String networkRead = String.Empty;
try
{
networkRead = new StreamReader(stream).ReadToEnd();
}
catch (Exception e) { }
return networkRead;
}
The send and recieve are identical for server and client. I intend to add error handling more when the messages are working.
I'm wondering that possibly there is an issue with my connection. Currently I am running 2 instances of the chat program on my machine, one server one client. The client connects at 127.0.0.1 (localhost) on port 8080 when the server is listening to port 8080. However the client does not connect at 192.168.1.100, which is my computer's actual ip, not sure if that might indicate something.
EDIT: adjusted the write and read to use stream writer and reader and flush
1.First of all , I will suggest you to make sure that your connection has been really established between your client and server.
2.Secondly, I will suggest you to flush your stream after you write, there are cache mechanism built in Stream, write to stream doesn't mean it will be send across the wire immediately.
3.It is a good way to learn networking in this way, but if you are creating commercial product, I will suggest you to look for some mature open source components.
Related
I'm working on a TCP connection where my client connects to a server's IP on 2 different ports. So I have 2 instances of TcpClient objects, one connecting to the IP on port 9000 and the other on port 9001.
The aim of 2 connections is that the server uses the active connection on port 9000 to give certain responses to the client frequently, and the client uses these responses to form and send a request on port 9001.
Now, the first time I connect on 9000, I get a response, I then form a request and fire off via 9001. Now I have a feeling I'm doing something wrong with the way I'm managing asynchronous requests to both ports, but I can't figure an alternate way of doing this:
IPAddress IPAddress = IPAddress.Parse("192.168.1.10");
public static async Task ConnectToPort9000()
{
TcpClient TcpClient1 = new TcpClient();
try
{
await TcpClient1.ConnectAsync(IPAddress, 9000);
if (TcpClient1.Connected)
{
byte[] Buffer = new byte[1024];
while (await TcpClient1.GetStream().ReadAsync(Buffer, 0, Buffer.Length) > 0)
{
//Server returns a message on this port
string Port9000Response = Encoding.UTF8.GetString(Buffer, 0, Buffer.Length);
//Setting ConfigureAwait(false) so that any further responses returned
//on this port can be dealt with
await Task.Run(async () =>
{
await SendRequestToPort9001BasedOnResponseAsync(Port9000Response);
}).ConfigureAwait(false);
}
}
}
catch (Exception)
{
throw;
}
}
private async Task SendRequestToPort9001BasedOnResponseAsync(string Port9000Response)
{
//Open connection on port 9001 and send request
TcpClient TcpClient2 = new TcpClient();
await TcpClient2.ConnectAsync(IPAddress, 9001);
if (TcpClient2.Connected)
{
//Handle each string response differently
if (Port9000Response == "X")
{
//Form a new request message to send on port 9001
string _NewRequestMesssage = "Y";
byte[] RequestData = Encoding.UTF8.GetBytes(_NewRequestMesssage);
new SocketAsyncEventArgs().SetBuffer(RequestData, 0, RequestData.Length);
await TcpClient2.GetStream().WriteAsync(RequestData, 0, RequestData.Length);
await TcpClient2.GetStream().FlushAsync();
//Handle any responses on this port
//At this point, based on the request message sent on this port 9001
//server sends another response on **port 9000** that needs separately dealing with
//so the while condition in the previous method should receive a response and continue handling that response again
}
else if (Port9000Response == "A")
{
//Do something else
}
}
}
The issue I am having at the moment is, after I send the request on port 9001, when processing any response messages on port 9001, the server has already sent me a response on port 9000, but my while loop on the first method isn't getting triggered, and it seems like that's because it's still executing the second method to process request/response on port 9001. I tried using ConfigureAwait(false) to basically fire and forget, but it doesn't seem to be working. Am I handling asynchronous processes the wrong way? Or should I look at alternatives such as action/delegates?
The aim of 2 connections is that the server uses the active connection on port 9000 to give certain responses to the client frequently, and the client uses these responses to form and send a request on port 9001.
Please don't do this. Socket programming is hard enough without making it extremely more complicated with multiple connections. Error handling becomes harder, detection of half-open connections becomes harder (or impossible), and communication deadlocks are harder to avoid.
Each socket connection is already bidirectional; it already has two independent streams. The only thing you need to do is always be reading, and send as necessary. The read and write streams are independent, so keep your reads and writes independent.
I'm trying to read incoming messages using a TcpListener. I set up a listener and I get a message. But the message is very strange. I'm getting this:
▬♥♥¡☺?♥♥YÄÂb #ù÷"MDòs←ç→.ge ûjò8┼#i(♥→å:À#À'<À%À)g#À À‼/À♦À♫32À+À/oÀ-À1z¢À↕▬‼ÿ☺:▬¶↨↑↓▬¶♠♥♠☺♣♥♣☺♦♥♦☺♦☻☻♥☻☺☻☻
The message is sent from another application (I don't have the source code of this application) over https (is it possible that the https is the problem?). Anyway, the listener I set up looks like this:
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 11000);
Console.WriteLine("Listening...");
listener.Start();
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Connection accepted.");
Thread t = CreateThread(client, false);
t.Start();
}
private static Thread CreateThread(TcpClient client)
{
Thread t = new Thread(delegate ()
{
byte[] data = new byte[300];
client.Client.Receive(data);
Console.WriteLine("Received data: ");
string value = Encoding.Default.GetString(data);
Console.WriteLine(value);
});
return t;
}
The message should be a valid xml tree. I'm using C# and .NET framework 4.5.2. What exactly am I doing wrong?
As the comments have said, it would appear that you're trying to get the data at a low level on the OSI model. Instead of using a TcpClient you can use a HttpClient to get the data from the application you're listening to.
Although it does depend on what your server is and how requests are handled.
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(uri);
Another solution is to use a StreamReader on your existing TCP connection, an example of that is in the question below. Although solution really depends on what your server it.
How reading messages from Server? (tcp)
If you are calling a web-service that uses soap/xml then use a web-service client ( add a Web Reference to your visual studio project )
Use an System.Net.Http.HttpClient or a System.Net.WebClient to download an xml file from a web-server.
No not try and decode encrypted web traffic using a TCP client.
I've got a little problem with the .Net Sockets in C#.
I programmed a client and a server working with TCP.
As the client is opened it sends a handshake to the server. The server answers with it's state (clientexists, clientaccepted,...). After that the application sends a getdata-request, abandons the connection and listens for the server's 'response'. Now, the server builds a connection to the client and sends all the data the client needs.
The code and everything else works, but the problem:
On our company testserver it works fine, on the live server only the handshake works. After it the client doesn't receive any more data. Serverapplication is the same on both servers.
I thought the problem was caused by some firewall (server wants to build a tcp connection to the client -> not good), but the system administrator said there is no firewall that could block that.
Now I'm searching for a ('cheap') solution that doesn't take too much time and changes in code. If anyone knows how to theoretically solve that, that would be great.
BTW: I am not allowed to do anything on the live server other than run the serverapplication. I don't have the possibility to debug on this server.
I can't publish all of my code, but if you need to see specific parts of it, ask for it please.
---EDIT---
Client-Server communication
1) Client startup
Client send handshake (new tcp connection)
2) Server validates handshake and saves IP
Server responds with it's client state (same tcp connection)
3) Client acknowledges this response and abandons this connection
Client sends getdata-request (new tcp connection)
Client abandons this tcp connection, too
4) Server receives getdata-request and collects the needed data in the main database
Server sends all the collected data to the client (multiple tcp connections)
5) Client receives all data and displays it in it's GUI (multiple tcp connections and the order of the data is kept by working with AutoResetEvents and Counts of sockets to send)
This is the main part my code does. It's by far not the best but it was for me as I wrote it I guess. Step one, two and three work as intended. The processing of the data works fine, too.
Another thing i forgot to mention is that the solution uses two Ports '16777' and '16778'. One to receive/listen and one to send.
My code is based on the MSDN example of the asynchronous server and client.
Sending a handshake (and getdata-request)
public void BeginSend(String data)
{
try
{
StateObject state = new StateObject();
state.workSocket = sender;
byte[] byteData = Encoding.UTF8.GetBytes(data);
sender.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback((IAsyncResult e) =>
{
Socket socket = (Socket)e.AsyncState;
SocketBase.StateObject stateObject = new SocketBase.StateObject();
stateObject.workSocket = socket;
socket.BeginReceive(stateObject.buffer, 0, 256, SocketFlags.None, new AsyncCallback(this.ReadCallback), (object)stateObject);
}), sender);
sender = RetrieveSocket(); //Socketreset
Thread.Sleep(100);
}
catch /*(Exception e)*/
{
//--
}
}
Server listener
public void StartListening()
{
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(System.Int32.MaxValue);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
//--
}
}
public void AcceptCallback(...);
public void ReadCallback(...);
Socket send
private void Send(Socket handler, String data)
{
Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address);
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device.
t.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), t);
}
Socket send all data part (answer to getdata-request | socToHandle should be the socket of the previous connection of the getdata-request)
private void SendAllData(Socket socToHandle, string PakContent)
{
#region IsThereADatetime? //Resolve a given datetime
#region GiveClientNumberOfPackets //Send the client info about how much he has to receive (See line below)
Send(socToHandle, "ALERT#TASKCOUNT;OPT-" + GetBestDate(dateStart) + EndSocket);
#region #SendResouces
#region #SendGroups
#region #SendTasks
}
Looking through my old code I have one idea =>
Could I send everything over the same connection by changing:
Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address);
(which creates a new connection) to something that uses the same connection?
If that would work, how can I do that?
And would the listener part of the client still receive single packets?
Servers and their environment are configured to handle incoming requests properly. Clients are usually behind a router, which by default make them unable to receive incoming connections from outside their network (a good thing).
To enable incoming connections, you could configure your router to forward all requests for a certain port number to your machine. No one else on your network would be able to run the client then, though.
This is why in a typical multiple clients-single server environment, the client makes all the connections, and only the server requires any changes to the network landscape.
I don't know why you chose to connect to the clients from the server side, but I would strongly advise against this - any cheap solution that uses this mechanism may turn out to be very expensive in the end.
I have an odd question. I am trying to write a C# server - client project using sockets for communication. I am new to C# but I have written the same project in Java and it worked just fine there.
So, the client connects to the server, creates the read/write streams from the socket's network stream and sends a single string through it but the server doesn't receive anything.
I am sure the server works fine because I have connected a Java client to it and it receives the string from client.
I don't understand how come the socket connects but nothing goes through it.
Here's the client's code:
...
socket = new TcpClient("localhost", PORT);
NetworkStream ns = socket.GetStream();
StreamReader rin = new StreamReader(ns);
StreamWriter wout = new StreamWriter(ns);
Console.WriteLine("-->Connected to server");
string msg;
for (; ; )
{
Console.WriteLine("waiting to write");
while(user.Equals("")) //user is set in Form thread working in parallel
System.Threading.Thread.Sleep(100);
Console.WriteLine("sending: " + user);
wout.WriteLine(user);
wout.Flush();
Console.WriteLine("SENT");
...
The PORT is the same, no exceptions are thrown (I have a try - catch around this), the client sends the string through the StreamWriter because it prints out "SENT" but the server waits at the receiving end (streamReader.ReadLine()) and nothing happens...
Try this:
socket = new TcpClient();
socket.Connect("localhost", PORT);
//... Your code continues here
I have a number of C# software applications that are add-ins for a peice of software that has a .net API.
for software licensing purposes I'm required to have a license server. I've got this, at the moment this is what it does:
when a tool is run, it contacts the license server with its computer name and username
the server recieves this request, logs the request, and checks to see if the number of requests from that machien and or user have exceeded the preconfigured maximum (2 different licensing types)
it does this using an encrypted file which lists the time, machine name, username etc
if its ok, it returns OKAY response to the computer and the tool then runs
if it doesnt return anything or if it returns a not OK response the tool will not run (the software only runs for a short time, but is regulary ran, as opposed to opening for a long time)
This works great, except I'm having a problem that the server randomly crashes, and users can't get onto it.
This is the first client-server app I've done and I'm a bit in the dark (and feel like I'm re-inventing something which is commonly used), is there any good guides for creating something like that? My apps is very simple, I have a service running on the server looping listening on a TCP port, waiting for something to be sent.
public void StartListening()
{
Listening = true;
// Set the TcpListener on port 41616.
Int32 port = 41616;
IPAddress localAddr = IPAddress.Any;
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
Listen();
}
public void Listen()
{
try
{
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while (Listening)
{
TcpClient client = server.AcceptTcpClient();
// 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);
Console.WriteLine("Received: {0}", data);
string returnData;
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = null;// DO STUFF BASED ON DATA
// set returnData to be the response (ie OKAY)
msg = System.Text.Encoding.ASCII.GetBytes(returnData);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", returnData);
// Shutdown and end connection
client.Close();
}
}
catch (Exception ex)
{
//LOG ERROR
}
finally
{
Listening = false;
server.Stop();
}
}
I have a feeling the server is hanging somewhere on the decryption /encryption of the license log, as the server runs fine for a while then just stops, and if i re-create the license log it works. But thats not the point of this post (though any tips on why I'm getting this error:
Error occured: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at BWSSLicenseServer.LicenseServer.Listen()
woudl be great)
My question is - how do I debug this easily in .NET? is there any good guides out there to help me? or is there any free framework for this? Should I be doing this code a totally different way (WCF, Web Service or something like that?)
ended up using CryptoLicensing as suggested in the comments
It may be something to do with the object expiring. Try adding this to your server class:
public override object InitializeLifetimeService()
{
return null;
}