I'm making an application in PhoneGap, and I'm using HTML5 Websockets to send some info to another device (read: sending data to another user who has the app). Users are registered with ID and Username.
For this, I read that I have to make an TCP/Socket connection. I've tried to use an old socket-chat I once made in school with C#.
I'm connecting to the socket this way from the app:
var ws = new WebSocket("ws://127.0.0.1:7001");
ws.onopen = function()
{
// Web Socket is connected, send data using send()
ws.send("message");
};
And the server side looks like this (of course isn't the entire code, but the relevant parts)
private NetworkStream stream;
private IFormatter formatter = new BinaryFormatter();
private TcpListener server;
public TcpClient client;
private string username { get; set; }
private void StartServer()
{
int port = Convert.ToInt32(portUser);
server = new TcpListener(IPAddress.Parse(IP), port);
server.Start();
client = server.AcceptTcpClient();
stream = client.GetStream();
username = formatter.Deserialize(stream).ToString();
}
The last deserialize-line writes:
The input stream is not a valid binary format. The starting contents (in bytes) are: 47-45-54-20-2F-20-48-54-54-50-2F-31-2E-31-0D-0A-48 ...
Any other way to deserialize the stream? Or am I using a completely wrong way?
Edit: working C# way I used to send data between clients in the chatter
stream = client.GetStream();
formatter.Serialize(stream, messageobj);
stream.Flush();
Related
I have separate client and server console apps. I'm simply trying to send a string from the client to the server and have the server write the string to the console using TcpClient. I can send a single message just fine but when I throw a while loop into the client app to try and send multiple messages without closing the TcpClient, the server doesn't write anything to the console.
//Server
using (TcpClient client = listener.AcceptTcpClient())
{
NetworkStream ns = client.GetStream();
byte[] buffer = new byte[1024];
while (true)
{
if (ns.DataAvailable)
{
int bytesRead = 0;
string dataReceived = "";
do
{
bytesRead = ns.Read(buffer, 0, buffer.Length);
dataReceived += Encoding.UTF8.GetString(buffer, 0, bytesRead);
}
while (bytesRead > 0);
Console.WriteLine($"Message:{ dataReceived }\n");
}
}
}
//Client
using (TcpClient client = new TcpClient(hostname, port))
{
if (client.Connected)
{
Console.WriteLine("Connected to server");
NetworkStream ns = client.GetStream();
string message = "";
//Removing this while loop I can send a single message that the server will write to console
//but with the loop present the server does not write anything
while (true)
{
message = Console.ReadLine();
byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(message);
ns.Write(messageBytes);
Console.WriteLine($"Message Sent! ({ messageBytes.Length } bytes)");
}
}
}
I'm interested in learning sockets and have been pouring over SO questions and MSDN docs for two days but cannot figure out why it's not working as I intend. I feel a bit silly even submitting a question because I'm sure it's something basic I'm not understanding. Could someone please drop some knowledge on me?
SOLUTION
//Server
using (TcpClient client = listener.AcceptTcpClient())
{
NetworkStream ns = client.GetStream();
StreamReader sr = new StreamReader(ns);
string message = "";
while (true)
{
message = sr.ReadLine();
Console.WriteLine(message);
}
}
//Client
using (TcpClient client = new TcpClient(hostname, port))
{
if (client.Connected)
{
Console.WriteLine("Connected to server");
NetworkStream ns = client.GetStream();
StreamWriter sw = new StreamWriter(ns) {Autoflush = true};
string message = "";
while (true)
{
message = Console.ReadLine();
sw.WriteLine(message);
}
}
}
If you debug your server, you'll see that it does receive data. You're just not displaying the data, because the only output your server does is after the loop when the byte count returned is 0: Console.WriteLine($"Message:{ dataReceived }\n");. The byte count will only be 0 when the underlying socket has been shutdown. That never happens because your client is stuck in an infinite loop.
A better approach, for a simple text-based client/server example like this, is to use StreamWriter and StreamReader with line-based messages, i.e. WriteLine() and ReadLine(). Then the line breaks serve as the message delimited, and your server can write the message each time it receives a new line.
Note also that in your example above, you are assuming that each chunk of data contains only complete characters. But you're using UTF8 where characters can be two or more bytes, and TCP doesn't guarantee how bytes that are sent are grouped. Using StreamWriter and StreamReader will fix this bug too, but if you wanted to do it explicitly yourself, you can use the Decoder class, which will buffer partial characters.
For some examples of how to correctly implement a simple client/server network program like that, see posts like these:
.NET Simple chat server example
C# multithreading chat server, handle disconnect
C# TcpClient: Send serialized objects using separators?
I have a robotic system that can be interacted with over TCP/IP. I have been able to control the system in Matlab using the following code:
AT = tcpip('cim-up',8000);
fopen(AT);
fprintf(AT, '$global[1] = 33');
I need to emulate the same command in C#. I have tried the following code:
// Connect to Robot using TCPIP
string IP = "cim-up";
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
try
{
tcpclnt.Connect(IP, 8000);
Console.WriteLine("Connected");
}
catch
{
Console.WriteLine("Failed");
}
StreamWriter AT_writer = new StreamWriter(tcpclnt.GetStream(), Encoding.ASCII);
AT_writer.Write("$global[1]=33");
This code will connect to the TCP/IP address but the server does not respond to the $global[1]=33 command.
I have also tried the following:
Byte[] data = System.Text.Encoding.ASCII.GetBytes("$global[1]=33");
// Get a client stream for reading and writing.
NetworkStream stream = tcpclnt.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Does anyone have any suggestions as I have a successful Matlab implementation?
Thanks
I have written a TCPClient program to run on my PC. It first initiates a TCP listener to listen on a specific port then reads/writes from/to multiple TCP clients on multiple threads.
I am able to read from the client but whenever I try to send data to it, the program displays that it has sent the data, but the client does not receive anything.
Here's the code:
TcpClient client = listener.AcceptTcpClient();
var childSocketThread = new Thread(() =>
{
if (client.Connected)
{
using (NetworkStream stream = client.GetStream())
{
Console.WriteLine("connected");
byte[] data = new byte[1000];
try
{
if (stream.CanRead)
{
stream.Read(data, 0, 1000);
string dataStr = Encoding.ASCII.GetString(data);
string dataa = dataStr.TrimEnd('\0');
//Console.WriteLine(dataa);
if (dataa.Length > 10)
{
deviceid = ParseRequest(dataa);
byte[] sendnow = Encoding.ASCII.GetBytes(reply[deviceid]);
Array.Clear(data, 0, 1000);
Console.WriteLine("Recieved data: " + dataa);
Console.WriteLine("Sending data");
using (StreamWriter writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
writer.WriteLine(reply[deviceid]);
}
Console.WriteLine(reply[deviceid]);
Console.WriteLine("Sent");
}
Console.WriteLine();
}
}
catch (Exception es)
{
Console.WriteLine(es);
}
}
}
});
childSocketThread.Start();
The server device that I am using is a PLC. Also, things I have already tried:
1) sending directly using Socket.Send method.
2) sending directly using NetworkStream method.
3) accepting the TCP connection as sockets. (Socket device = listener.AcceptSocket).
None of these methods seem to send to the device, even though the program tells me that it had no issues sending data since it displays "Sent" after attempting to send data.
I downloaded another program from this link http://www.codeproject.com/Articles/488668/Csharp-TCP-Server. The test app they provide with it is able to send and receive data on the same port as my program running on the same PC.
I haven't been able to get any direction on how to diagnose and more importantly solve this issue. Any ideas?
Update 2015-08-10 11:18 a.m.:
Output of the Program is as follows:
Update 2015-08-10 11:32 a.m.:
Output of Syslog Console:
Update 2015-08-10 12:07 p.m.:
Output of Wireshark:
We need you to post both sides code. Nevertheless, here is some code that works just fine, you can use it to see if you are doing something wrong.
http://www.codeproject.com/Articles/1415/Introduction-to-TCP-client-server-in-C
I'm working on a biometry system with my C# application.
Sdk provices a connection via TCP/IP on port 2100, and works by receiving and sending strings to communicate .
My class:
class Biometry
{
private System.Net.Sockets.TcpClient _clientSocket = new System.Net.Sockets.TcpClient();
public Biometry() {
//connect to socket
_clientSocket.Connect("127.0.0.1", 2100);
_clientSocket.ReceiveTimeout = 9000;
}
public String identify(String msg) {
//get network stream
NetworkStream _serverStream = _clientSocket.GetStream();
//send an array of bites that represents a string(encoded)
System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(msg);
_serverStream.Write(outStream, 0, outStream.Length);
//reads the response from networkStream
byte[] inStream = new byte[10025];
_serverStream.Read(inStream, 0, (int)_clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
_serverStream.Close();
return returndata;
}
}
The problem is:
It is not working!! The biometry only works(SDK only understand my request) when I close the application(connection is closed).
You might need to flush the stream before your start reading using _serverStream.Flush().
Another problem might be that in your question you say you need to connect to port 21000, but in your code you connect to 2100, which might be a typo in either place, but should be fixed ;-)
In addition to flushing the stream, your server might also be waiting for an "end of message" indicator?
I am writting a C# P2P Video Chat (Part of my exam on Faculty),a i am little stuck at send Data via udp. So here how it works. I have a Web_Capture library, and every time image is captured it sets PictureBox image to the captured one
private void webCamCapture_ImageCaptured(object source, WebCam_Capture.WebcamEventArgs e)
{
myCamera.Image = e.WebCamImage;
sendData(ref ipep2); // send it immediately
}
So then the sendData method starts sending...
private void sendData(ref IPEndPoint sender)
{
byte[] data;
if (friendsClient == null)
{
friendsClient = new UdpClient();
}
MemoryStream myStream = new MemoryStream();
myCamera.Image.Save(myStream, System.Drawing.Imaging.ImageFormat.Jpeg);
data = myStream.GetBuffer();
friendsClient.Send(data, data.Length,sender);
}
When i debug, the socket exception pops out:
System.Net.Sockets.SocketException was unhandled by user code
Message=The requested address is not valid in its context
Source=System
ErrorCode=10049
NativeErrorCode=10049
So, does anyone have any idea, i will be thankfull if he support that idea with code, because i am nooby at c# :) thanks in advance. Marjan
You should specify reciever's ip and port, Here is a complete example
so you should change your implementation to
private void sendData(ref IPEndPoint reciever)
{
byte[] data;
Socket sending_socket = new Socket(AddressFamily.InterNetwork, ocketType.Dgram, ProtocolType.Udp);
MemoryStream myStream = new MemoryStream();
myCamera.Image.Save(myStream, System.Drawing.Imaging.ImageFormat.Jpeg);
data = myStream.GetBuffer();
sending_socket.SendTo(data, reciever);
}