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
Related
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 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.
tcpListener = new TcpListener(IPAddress.Any, 6007);
tcpListener.Start();
while (true)
{
TcpClient client = tcpListener.AcceptTcpClient();
sw = new StreamWriter(client.GetStream());
sr = new StreamReader(client.GetStream());
while(true)
parseRequest(sr.ReadLine());
}
This is essentially the code I am using for a C# tcp server. The server needs to handle multiple connections, but not simultaneously, so it can work with one client, and when that client disconnects continue on to the next client. The client can send a variable amount of messages, and the server needs to process these messages.
The problem is when the first client disconnects it never connects to the next client. I tried adding code in my second while loop to check "if (!Client.Connected) break; " but Connected always returned true, even after my client application had closed out. What can I do to be able to connect to the second client after the first has disconnected?
You need to start a new thread or register a new listener for each accepted socket, instead of processing it entirely in the same loop that is accepting new clients. The accept loop should do nothing else.
I'm working on a system to send data between peers on a network. One app is written in Java for the Android. The other app is written in C# on the PC.
I wrote code in Java on the Android to send UDP datagrams. And I wrote C# code to both send and receive datagrams. I tried to send messages from Android to PC. I could see the message in WireShark but not in my program. So, I put my program on a second PC. I succeeded in sending a message from my PC to the second one. But when I tried to send a message from seond PC back to mine it failed. I could see it in WireShark on my PC but not my application. Im at a loss for what to try next. Do you have any suggestions? Why would the UDP packet be visible in WireShark but not my application?
Here is my code.
//C# code on PC
//Sender
sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, rotocolType.Udp);
send_to_address = IPAddress.Parse(strIPAddress);
sending_end_point = new IPEndPoint(send_to_address, intPort);
sending_socket.EnableBroadcast = true;
byte[] bytMessage = Encoding.ASCII.GetBytes(strMessage);
sending_socket.SendTo(bytMessage, sending_end_point);
//Listener
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] bytReceiveDataByteArray;
try
{
listener.EnableBroadcast = true;
while (isRunning)
{
//listen for data from sender
bytReceiveDataByteArray = listener.Receive(ref groupEP);
//Fire an event to send the data to the hosting code
if (DataReceived != null)
{
DataReceivedEventArgs e = new DataReceivedEventArgs(bytReceiveDataByteArray);
DataReceived(this, e);
}
}
}
//Java code on Android
DatagramSocket socket = new DatagramSocket();
InetAddress serverIP = InetAddress.getByName(strIpAddress);
byte[] outData = (strMsg).getBytes();
DatagramPacket out = new DatagramPacket(outData,outData.length, serverIP,50005);
socket.send(out);
socket.close();
Thanks,
Mike
If I understand the problem correct when your program runs on a specific PC (lets call it "Windows1") it never receives the UDP packets. It will not receive them from Java Android or from C# code running on a different PC ( lets call it "Windows2").
However when you run your program on "Windows2" it DOES receive messages from "Windows1". Sounds like you have the firewall enabled on "Windows1" and do not have an exception for UDP port 50005. On "Windows2" your firewall is turned off or has the exception for 50005 and this is why it receives messages from "Windows1".
Note that since UDP is not connection oriented, firewall errors will not cause the usual connection timed out error. The messages are just dropped and you never get an error.
I am new to both C# and to client-server programming. Right now, for class, I'm attempting to create an FTP client without using any pre-established FTP libraries. I feel like I have the project down for the most part, however I'm running into a problem when I make more than one call that requires use of the data port (list, retr, etc.) Here is a sample of the code that is breaking:
writer.WriteLine(portcmd);
writer.Flush();
GetServerMessage(stream);
writer.WriteLine("list ");
writer.Flush();
tmpserver = new TcpListener(IPAddress.Any, 3128);
tmpserver.Start();
tmpclient = tmpserver.AcceptTcpClient();
Console.WriteLine("gothere");
if (!tmpclient.Connected)
{
tmpserver.Start();
}
StreamReader tmpreader = new StreamReader(tmpclient.GetStream());
GetServerMessage(stream);
while (tmpreader.Peek() != -1)
{
Console.WriteLine(tmpreader.ReadLine());
}
tmpclient.Close();
tmpserver.Stop();
GetServerMessage(stream);
Getservermessage is a method that takes a network stream and prints out everything available within a .5 second timeout, stream is the NetworkStream for the current connection to the FTP server, and writer is that same network stream wrapped in a StreamReader for ease of writing ASCII characters to the server. In case you are wondering why I use a stream reader to read from the data connection, it is because the server closes the connection after it transmits the data so I could easily get an eof notification. My GetServerMessage method was for some reason breaking when I used the closed network stream.
This code is sending the port command to the FTP server to inform it that I will be requiring a data connection (first 2 lines) Then sending the list command, establishing the data connection to the server, getting the desired information, and then terminating the data connection (the rest of the code).
This code will execute without flaw the first time I run it but if I try it again, it hangs on the 'tmpclient = tmpserver.AcceptTcpClient();' line. It never reaches the "gothere" print statement. I believe this is because I am receiving the client from the same machine on the same port but I'm not sure. I tried adding a Boolean value to make sure the AcceptTcpClient() only ran once but then I got a runtime error and visual studio informed me that I may have 'released resources before I was done with them' I predicted this would be a problem but how can I tell if the server reestablishes the connection after it has closed it once?
At the end of the given code I stop tmpserver and close tmpclient. I originally did this because I knew the FTP server would close the connection when it was finished transmitting and thought it was the proper thing to do. I find if I comment out these lines, the code will execute more than once but the streams appear to be empty... I'm not sure if this information is helpful but I figured I'd mention it.
I apologize if I am unclear at all but my lack of knowledge with the subject makes it difficult to articulate my problem. If there is any confusion over what the problem is I'd be happy to attempt to clear it up.
To be able to accept another client you should execute tmpclient = tmpserver.AcceptTcpClient(); and waiting for the first client to finish its works(before accepting second client) may not be a good idea
Here is a sample server code that waits for the connections and echoes strings sent from each client. You can test it with telnet localhost 3128
Thread t = new Thread(Server);
t.IsBackground = true;
t.Start();
-
void Server()
{
TcpListener listener = new TcpListener(IPAddress.Any, 3128);
listener.Start();
while (true)
{
var client = listener.AcceptTcpClient();
new Thread(() =>
{
using (client)
{
var reader = new StreamReader(client.GetStream());
var writer = new StreamWriter(client.GetStream());
while (true)
{
string line = reader.ReadLine();
if (line == "QUIT") break;
writer.WriteLine("From Thread[" + Thread.CurrentThread.ManagedThreadId + "] > " + line);
writer.Flush();
}
}
}).Start();
}
}
OK, it's like this. To do a server in a simple manner, you need to thread off the code that handles the client socket. When the accept returns, create and start a thread, passing it the 'tmpclient' and then loop around to the accept call again so that any new client can connnct up. In the newly-spawned server<> client thread, read and write to the passed socket in a loop to communicate with the client.
Once you close your tcp client stream, you can no longer read from the stream you pulled from it.
var stream = tcpClient.GetStream();
...
tcpclient.Close();
...
stream.Read .. fail
The client would have to request another connection,
OR
You should keep your tcp client sockets open.
More complex servers will keep some metadata (state) cached about the client so when sockets unexpectedly close - and the client quickly tries to reconnect, the server can continue processing the smoothly.