im making a Window Application in C# using Socket Programming. I have developed a Server & a Client. Both are working fine but the problem which im gettin is that when ever i send any message from CLIENT, its send perfectly and receives on SERVER but whenever i try to send any message from SERVER it doesn't send to Client, since at the beginning when a connection is built, server sends the message to client that "Connection Established" and received at Client perfectly,but later on server does not send any message to client!!! Could anyone please help me out ???????
Regards
Umair
EDIT:
//Code at SERVER for SENDING...
private void button_send(object sender, EventArgs e)
{
string input = textBoxWrite.Text;
byte[] SendData = new byte[1024];
ASCIIEncoding encoding = new ASCIIEncoding();
SendData = encoding.GetBytes(input);
client.Send(SendData,SendData.Length,SocketFlags.None);
textBoxShow.Text = "Server: " + input;
}
//Code at CLIENT for receiving
NetworkStream networkStream = new NetworkStream(server);
string input = textBoxUser.Text + ": " + textBoxWrite.Text;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] inputByte = encoding.GetBytes(input);
if (networkStream.CanWrite)
{
networkStream.Write(inputByte, 0, inputByte.Length);
textBoxShow.Text = textBoxShow.Text + Environment.NewLine + input;
textBoxWrite.Text = "";
networkStream.Flush();
}
I'm not sure how best to help based on the information you've provided, but perhaps you could look at something like this example of C# socket programming and compare with your own application.
Related
I'm attempting to create a bare bones websocket chat room server. My client is able to connect to the server, but it is unable to send messages to the server, despite the server being in a listening state.
When the client connects, a bunch of what looks like header information gets written to the console. But when WebSocket.send() gets executed in Javascript, nothing occurs server side.
HTML:
<button id="closeSocket">disconnect</button><br />
<input id = "inputField" /><button id="sendMessage">send</button>
<div id = "output"></div>
<script type = 'text/javascript' src = 'websockets.js'></script>
Javascript:
websocket = new WebSocket("ws://127.0.0.1:80");
document.getElementById("closeSocket").onclick = closeSocket;
document.getElementById("sendMessage").onclick = sendMessage;
websocket.onopen = function(){
output("connected");
}
function sendMessage(){
output("sent: " + document.getElementById('inputField').value);
websocket.send(document.getElementById('inputField').value);
}
websocket.onmessage = function(e){
output("got response: " + e.data);
}
function closeSocket(){
websocket.close();
}
websocket.onclose = function(){
output("disconnected");
}
function output(t){
document.getElementById("output").innerHTML += t + "<br />";
}
C# server:
using System;
using System.Net;
using System.Net.Sockets;
namespace WebSocketsTutorial {
class Program {
static void Main(string[] args) {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
TcpClient client = default(TcpClient);
server.Start();
Console.WriteLine("server started");
while (true) {
client = server.AcceptTcpClient();
byte[] receivedBuffer = new byte[100];
NetworkStream stream = client.GetStream();
stream.Read(receivedBuffer, 0, receivedBuffer.Length);
foreach (byte b in receivedBuffer) {
Console.Write(Convert.ToChar(b).ToString());
}
}
}
}
}
This is what is output on the console when the client connects:
What I'm mainly looking to do is to allow an arbitrary number of connections and ultimately have the server echo a user's submission to all connected clients.
First of all, a WebSocket is not just a regular socket. It defines a connection handshake using HTTP and its own framing protocol that you need to use.
https://en.wikipedia.org/wiki/WebSocket
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
https://hpbn.co/websocket/
Second, you are reading just the first 100 bytes of the request. You should read until the Read operation returns 0.
There is a myriad of components you can use to create a WebSocket server, including the default one: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/websockets
I'm trying to create a little program in c# to deal with the xiaomi smart home api.
Api translation
I'm stuck at the beginning. I don't achieve to send {"cmd" : "get_id_list"} to the gateway and receive the response.
I'm trying to use this code to send but I've got nothong in response :
string i = "{\"cmd\" : \"get_id_list\"}";
UdpClient client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("192.168.1.112"), 9898);
Byte[] buffer = null;
buffer = Encoding.Unicode.GetBytes(i.ToString());
client.Send(buffer, buffer.Length, ep);
byte[] b2 = client.Receive(ref ep);
string str2 = System.Text.Encoding.ASCII.GetString(b2, 0, b2.Length);
192.168.1.112 is my gateway ip adress.
Here a screenshot of packet senders software on windows : Screenshot
We can see that the gateway reply to me the right informations.
So how to get this reply whatever the response port ?
thank for your help
As #jdweng suggests, you need to use a Connect() method on your UDP client, or it won't listen for responses. You can either do this, or use two separate UdpClients, one to send and one to receive.
string i = "{\"cmd\" : \"get_id_list\"}";
UdpClient client = new UdpClient();
client.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.112"), 9898));
Byte[] buffer = null;
buffer = Encoding.Unicode.GetBytes(i.ToString());
client.Send(buffer, buffer.Length, ep);
byte[] b2 = client.Receive(ref ep);
string str2 = System.Text.Encoding.ASCII.GetString(b2, 0, b2.Length);
I have a socket server (written on C++) which receives requests from clients and sends responses back. So, my test client application (C#) is very simple:
try {
UdpClient udpClient = new UdpClient(10241);
// Connect
udpClient.Connect(server_ip_address, 10240);
// prepare the packet to send
iWritableBuff wbuff = new iWritableBuff();
[ ... ]
// Send
udpClient.Send(wbuff.GetBuff(), (int)wbuff.Written());
// Receive a response
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
Console.WriteLine("We've got some data from the server!!! " + receiveBytes.Length + " bytes.");
udpClient.Close();
} catch (Exception e) {
Console.WriteLine("ERROR: " + e.ToString());
}
I run both applications on the same computer. Server receives a request to port 10240 from the client port 10241 and sends a response back to client port 10241, but client never receive it. So, I'm sure that server sends packet back, because everything works perfectly with C++ client. It means that I'm, doing something wrong on my C# client. Any idea?
Thanks!
P.S.> Just test it with Berkley Socket C# client:
try {
// Create socket
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// Bind
IPEndPoint myEP = new IPEndPoint(IPAddress.Any, 0);
s.Bind(myEP);
// prepare the packet to send
iWritableBuff wbuff = new iWritableBuff();
[ ... ]
// Send it
IPEndPoint sEP = new IPEndPoint(IPAddress.Parse(server_ip_address), 10240);
int res = s.SendTo(wbuff.GetBuff(), (int)wbuff.Written(), 0, sEP);
// Receive the response
byte[] receiveBytes = new Byte[1024];
EndPoint recEP = new IPEndPoint(IPAddress.Any, 0);
res = s.ReceiveFrom(receiveBytes, ref recEP);
Console.WriteLine("We've got some data from the server!!! " + res + " bytes.");
} catch (Exception e) {
Console.WriteLine("ERROR: " + e.ToString());
}
And it works perfect! What's is wrong with UdpSocket?
Not sure if this applies to UDPClients that don't broadcast packets but simply send one to a specified address, but I ran into a similar roadblock.
I had a UDPClient that broadcasted a udp packet for discovery of some custom machines on our network. When I tried to receive the message that the servers would simply echo back, it would not receive the information and would timeout. Turns out that if you use a UDPClient that broadcasts a message out, it WILL NOT be able to receive messages back. It's not documented anywhere, except for one forum topic on msdn that I luckily came across.
The solution was to send the message, immediately close the socket, open a NEW UDPClient on the same port, then use this new UDPClient to receive the echoed back UDP packet. Very annoying.
Give that a shot and see if it works. It definitely works for sending out a broadcasted packet.
i have to implement push notification in my project.
It has sender(windows phone window application),wcf service and client(windows phone applcation).
How can i replace the sender and use my url to send and recieve notification from client?
i want sender to be some application in emulator itself that run parallely with the client and push data continously to the client.
how to develop such application
can anyone tell the way.
It sounds as though you are looking to use two WP7 apps to send messages back and forth to one another using the push notification functionality. Is that correct?
My understanding it that you will still require a each device to subscribe to a push notification service (MS hosted) using the unique URI sent back when the subscription is successful. It appears that SL3/4 can create HttpWebRequest objects and therefore should be able to formulate a correct package to send, however, the difficulty as I see it will be how to obtain the URI of the device you want to send the post to. Normally the post is sent to the subscriber, which knows its on URI as it was returned during the subscribing phase.
My WCF hosted code only works if the WCF knows the URI of the device, which is sent when the WCF method is called:
public bool sendTileUpdate(string tileText, string url, string image)
{
string TilePushXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Tile>" +
"<wp:BackgroundImage>{2}</wp:BackgroundImage>" +
"<wp:Count>{0}</wp:Count>" +
"<wp:Title>{1}</wp:Title>" +
"</wp:Tile>" +
"</wp:Notification>";
try
{
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(url);
sendNotificationRequest.Method = "POST";
sendNotificationRequest.Headers = new WebHeaderCollection();
sendNotificationRequest.ContentType = "text/xml";
// Tile
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");
sendNotificationRequest.Headers.Add("X-NotificationClass", "1");
string str = string.Format(TilePushXML, "", tileText, image);
byte[] strBytes = new UTF8Encoding().GetBytes(str);
sendNotificationRequest.ContentLength = strBytes.Length;
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(strBytes, 0, strBytes.Length);
}
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
return true;
}
catch (Exception e)
{
return false;
}
}
I know this is a TileNotification, but the principles are the same.
I understand that Mango (WP7.1 & SL4) will support sockets and this might be a more appropriate way for your devices to communicate!
Good luck,
Jason.
I am trying to get EWS's push notifications set up in my c# app.
After getting the response from the server and reading it using a NetworkStream I need to respond to the server with Ok in a SOAP message. The only example that I can find uses Microsoft.Web.Services3 and a SoapEnvelope. My understanding is that this has now been replaced by WCF and I really want to use the newer technologies (to learn them).
How would I go by sending a SOAP message back to the server, presumably using the same NetworkStream that I get the notification on?
Here is some code that I tried, but it fails for some reason.
const string RESPONSE_OK = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope\"><soap:Body>" +
"<SendNotificationResult xmlns=\"http://schemas.microsoft.com/exchange/services/2006/messages\">" +
"<SubscriptionStatus>OK</SubscriptionStatus></SendNotificationResult></soap:Body></soap:Envelope>";
responseBytes = encoding.GetBytes(RESPONSE_OK);
// Send the result
HTTPResponseStruct _httpResponse;
_httpResponse.version = "HTTP/1.1";
_httpResponse.BodyData = responseBytes;
_httpResponse.Headers = new Hashtable();
_httpResponse.Headers.Add("Server", "IT12");
_httpResponse.Headers.Add("Date", DateTime.Now.ToString("r"));
_httpResponse.Headers.Add("Content-Type", "text/xml; charset=utf-8");
_httpResponse.Headers.Add("Content-Length", _httpResponse.BodyData.Length);
_httpResponse.Headers.Add("Connection", "close");
string HeadersString = _httpResponse.version + " "
+ "200 OK" + "\r\n";
foreach (DictionaryEntry Header in _httpResponse.Headers)
{
HeadersString += Header.Key + ": " + Header.Value + "\r\n";
}
HeadersString += "\r\n";
byte[] bHeadersString = Encoding.ASCII.GetBytes(HeadersString);
// Send headers
clientStream.Write(bHeadersString, 0, bHeadersString.Length);
// Send body
if (_httpResponse.BodyData != null)
clientStream.Write(_httpResponse.BodyData, 0,
_httpResponse.BodyData.Length);
// clientStream.Write(responseBytes, 0, responseBytes.Length);
clientStream.Flush();
Thanks,
Pieter
you can use Microsoft.Exchange.WebServices.Data (EWS Managed API Reference)
http://msdn.microsoft.com/en-us/library/dd633710%28v=EXCHG.80%29.aspx
You marked the other answer as "accepted" but the link you are referring to talks about streaming subscriptions. These are only available for Exchange 2010 and later. For those who are stuck with Exchange Server 2007, there is a Push-Notification library on CodePlex.