This might be a piece of cake for any experienced C# developer
What you see here is a sample Asynchronous webserver
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SimpleServer
{
class Program
{
public static void ReceiveCallback(IAsyncResult AsyncCall)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] message = encoding.GetBytes("I am a little busy, come back later!");
Socket listener = (Socket)AsyncCall.AsyncState;
Socket client = listener.EndAccept(AsyncCall);
Console.WriteLine("Received Connection from {0}", client.RemoteEndPoint);
client.Send(message);
Console.WriteLine("Ending the connection");
client.Close();
listener.BeginAccept(new AsyncCallback(ReceiveCallback), listener);
}
public static void Main()
{
try
{
IPAddress localAddress = IPAddress.Parse("127.0.0.1");
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 8080);
listenSocket.Bind(ipEndpoint);
listenSocket.Listen(1);
listenSocket.BeginAccept(new AsyncCallback(ReceiveCallback), listenSocket);
while (true)
{
Console.WriteLine("Busy Waiting....");
Thread.Sleep(2000);
}
}
catch (Exception e)
{
Console.WriteLine("Caught Exception: {0}", e.ToString());
}
}
}
I downloaded this from the web, in order to have a basic model to work on.
Basically what I need to do is run this webserver as a process in a computer. It will be listening to por 8080 all the time, and when a client computer sends a request, this server will process some data and send back a result as a string.
I created a small project with this code (which is functional as is), but when it executes the line
client.Send(message);
all I get is an error in the browser, or at most a blank page
I suspect I need to define the HTTP headers to send with the (message), but I have been searching the web on this with no luck
Anyone willing to help?
Thanks!
You need something like this
HTTP/1.1 200 OK
Server: My Little Server
Content-Length: [Size of the Message here]
Content-Language: en
Content-Type: text/html
Connection: close
[Message]
If you send this hole block of data it should work correctly.
Edit:
You can use this Method:
public static void SendHeader(string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
{
String sBuffer = "";
// if Mime type is not provided set default to text/html
if (sMIMEHeader.Length == 0)
{
sMIMEHeader = "text/html"; // Default Mime Type is text/html
}
sBuffer = sBuffer + "HTTP/1.1" + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: cx1193719-b\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
mySocket.Send(Encoding.ASCII.GetBytes(sBuffer),Encoding.ASCII.GetBytes(sBuffer).Length, 0);
Console.WriteLine("Total Bytes : " + iTotBytes.ToString());
}
And in your Main()-Method you should replace
Byte[] message = encoding.GetBytes("I am a little busy, come back later!");
with
string messageString = "I am a little busy, come back later!";
Byte[] message = encoding.GetBytes(messageString);
and then insert
// Unicode char may have size more than 1 byte so we should use message.Length instead of messageString.Length
SendHeader("text/html", message.Length, "202 OK", ref client);
before
client.Send(message);
That's all.
Related
I have this web server program up and running, using TcpListener. The problem is that for each get request made through web browser (or chrome Postman extension), it captures two requests.
namespace Server
{
class WebServer2
{
private TcpListener listener;
private int port = 8080;
public WebServer2()
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
listener.Start();
Console.WriteLine("Listening...");
//start the thread which calls the method 'StartListen'
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
}
catch (Exception e)
{
Console.WriteLine("An Exception Occurred While Listening: " + e.ToString());
}
}
//Recieve Request
public void StartListen()
{
int iStartPos = 0;
String sRequest;
String sRequestedFile;
String sResponse = "";
while (true)
{
//Accept a new connection
Socket socket = listener.AcceptSocket();
if (socket.Connected)
{
Console.WriteLine("\nClient Connected");
Console.WriteLine("----------------");
//Receive data from the client
Byte[] bReceive = new Byte[1024];
int i = socket.Receive(bReceive, bReceive.Length, 0);
//Convert Byte to String
string sBuffer = Encoding.ASCII.GetString(bReceive);
//Only GET Request is accepted
if (sBuffer.Substring(0, 3) != "GET")
{
Console.WriteLine("Not a Get Request.");
socket.Close();
continue;
}
// Look for HTTP request
iStartPos = sBuffer.IndexOf("HTTP", 1);
// Get the HTTP text and version e.g. it will return "HTTP/1.1"
string sHttpVersion = sBuffer.Substring(iStartPos, 8);
// Extract the Requested Type and Requested file/directory
sRequest = sBuffer.Substring(0, iStartPos - 1);
//If file name not provided
if (sRequest.IndexOf(".") < 1)
{
Console.WriteLine("File name not Provided!");
socket.Close();
continue;
}
//Extract the requested file name
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
Console.WriteLine("Requested File: " + sRequestedFile);
int iTotBytes = 0;
sResponse = "";
FileStream fs = new FileStream(sRequestedFile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[fs.Length];
int read;
while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
// Read from the file and write the data to the network
sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
iTotBytes = iTotBytes + read;
}
reader.Close();
fs.Close();
SendHeader(sHttpVersion, "text/html", iTotBytes, " 200 OK", ref socket);
SendToBrowser(bytes, ref socket);
socket.Send(bytes, bytes.Length, 0);
socket.Close();
}
}
}
// Overloaded Function, takes string, convert to bytes and calls
// overloaded sendToBrowserFunction.
public void SendToBrowser(String sData, ref Socket socket)
{
SendToBrowser(Encoding.ASCII.GetBytes(sData), ref socket);
}
/// Sends data to the browser (client)
public void SendToBrowser(Byte[] bSendData, ref Socket socket)
{
int numBytes = 0;
try
{
if (socket.Connected)
{
if ((numBytes = socket.Send(bSendData, bSendData.Length, 0)) == -1)
Console.WriteLine("Socket Error");
}
else
Console.WriteLine("Connection Dropped!");
}
catch (Exception e)
{
Console.WriteLine("Error: {0} ", e);
}
}
// This function send the Header Information to the client (Browser)
public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket socket)
{
String sBuffer = "";
Byte[] bSendData;
if (sStatusCode.Equals("404") || sStatusCode.Equals("400"))
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Length: " + 0 + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
else
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
}
}
}
Single request made by chrome against http://localhost:8080/page1.html
Request made by Postman Extension
The funny thing is, everything works find when I send request through my client program (using TcpClient).
I tested your server and got similar results:
Chrome automatically asks for a favicon.ico file for every request. This generates the extra GET request to your server.
Firefox doesn't do this and simply generates one request per refresh.
Then there is a second problem I experienced, which is the one in your Postman screenshot.
Chrome (including the Postman Extension running inside it) reconnects
without sending anything, so the server "hangs" until you get a
response filled with \0 (nul-characters).
This is part of Chrome's prediction service to load subsequent requests faster. You could disable this behavior under Settings (advanced) > Privacy:
In your server implementation, this results in the "Not a Get Request" output if no subsequent GET request follows (instead, Chrome sends \0 to signal its not sending anything anyway).
Note: I didn't experience any of this in the actual Postman application.
While the server waits for chrome to send a request, it cannot service any other requests. To prevent this from happening, consider using an asynchronous approach.
I have a code there send a XML file to a UdpSocket and received an answer. I send and received the answer Asynchronous. My problem is, when I received the answer from UDP socket, I cannot save it to the right file. I have tried a lot of things, but nothing works.
To explain my code short. I start to make 3 AsynchronousConnection in the Main() method. Which call static void AsynchronousConnection(object objectFilename) from there I call the UdpStartClient method.
From UdpStartClient method I send a file with UdpSendXmlFile(fileToSend, udpClient, bytes, CallDuration, out threadId);
After that, I received the answer in a while loop with method UdpReceivedXmlFile("c:\Received" + filename, udpClient, remoteEPReceived, CallDuration, out threadId);
The answer I received in the UdpReceivedXmlFile method, will be save to a file. It is here my problem is, I think. I send 3 file by AsynchronousConnection and received 3 answer from the UDP socket, but the answers does not match the file I send.
For example I send these 3 files.
MessagingText4000.xml
MessagingText4001.xml
MessagingText8.xml
I received the answer randomly, for example:
File MessagingText4000.xml can get the answer from MessagingText8.xml
File MessagingText4001.xml can get the answer from MessagingText4000.xml
File MessagingText8.xml can get the answer from MessagingText4001.xml
Can you help me, so I received the right answer to the right file?
public delegate void AsyncMethodCall(object objectFilename, int callDuration, out int threadId, out string receivedXmlDataFromTNX);
// Program
public static void Main(String[] args)
{
Thread newThread;
newThread = new Thread(AsynchronousConnection);
newThread.Name = "4001";
newThread.Start("MessagingText4001.xml");
newThread = new Thread(AsynchronousConnection);
newThread.Name = "4000";
newThread.Start("MessagingText4000.xml");
newThread = new Thread(AsynchronousConnection);
newThread.Name = "8";
newThread.Start("MessagingText8.xml");
}
// Asynchronous Connection
static void AsynchronousConnection(object objectFilename)
{
int threadId; string receivedXmlData;
UdpClass udpClass = new UdpClass();
AsyncMethodCall caller = new AsyncMethodCall(udpClass.UdpStartClient);
IAsyncResult result = caller.BeginInvoke(objectFilename, 500, out threadId, out receivedXmlData, null, null);
result.AsyncWaitHandle.WaitOne();
caller.EndInvoke(out threadId, out receivedXmlData, result);
result.AsyncWaitHandle.Close();
}
// UdpClient received
void UdpReceivedXmlFile(object objectFilename, UdpClient udpClient, IPEndPoint remoteEPReceived, int CallDuration, out int threadId)
{
Thread.Sleep(CallDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
try
{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref remoteEPReceived);
File.WriteAllText((string)objectFilename, Encoding.UTF8.GetString(receiveBytes));
}
catch (Exception ex)
{
Console.WriteLine("Contact webmaster with this error in UdpReceivedXmlFile:\n " + ex.ToString());
}
}
// UdpClient send
void UdpSendXmlFile(string fileToSend, UdpClient udpClient, byte[] bytes, int CallDuration, out int threadId)
{
Thread.Sleep(CallDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
try
{
// Encode the data string into a byte array
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(fileToSend);
// Load XML fil
string xmlContent = xmlDoc.OuterXml;
byte[] msg = Encoding.UTF8.GetBytes(xmlDoc.OuterXml);
// Send the data through the socket.
udpClient.Send(msg, msg.Length);
}
catch (Exception ex)
{ Console.WriteLine("Contact webmaster with this error in UdpSendXmlFile:\n " + ex.ToString());
}
}
// UdpStart Client
public void UdpStartClient(object objectFilename, int CallDuration, out int threadId, out string receivedXmlData)
{
string filename = (string)objectFilename;
receivedXmlData = null; Thread.Sleep(CallDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
try
{
Console.WriteLine("1: UdpStartClient Async - id: " + threadId + " objectFilename: " + (string)objectFilename);
fileToSend = fileLocation + filename;
// Send a file to the UdpSocket
UdpSendXmlFile(fileToSend, udpClient, bytes, CallDuration, out threadId);
TimeSpan maxTime = TimeSpan.FromSeconds(10);
Stopwatch stopwatch = Stopwatch.StartNew();
bool stopwatchStop = false;
while (stopwatch.Elapsed < maxTime && !stopwatchStop)
{
// listed on UdpSocket and save to file
UdpReceivedXmlFileDirectToFile("c:\\Received" + filename, udpClient, remoteEPReceived, CallDuration, out threadId);
attributXMLReceived = ReadXmlAttribut("c:\\Received" + filename, CallDuration, out threadId);
if ((attributXMLReceived == "Status=Pending") || (attributXMLReceived == "Status=Sent"))
{
Console.WriteLine("Answer from XMl file:" + attributXMLReceived + " id: " + Thread.CurrentThread.ManagedThreadId + "\n");
}
else if (attributXMLReceived == "Status=Delivered")
{
Console.WriteLine("Answer from XMl file:" + attributXMLReceived + " id: " + Thread.CurrentThread.ManagedThreadId + "\n");
stopwatchStop = true;
}
if (stopwatch.Elapsed == maxTime)
Console.WriteLine("Timeout!");
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
That's how UDP works.
UDP is a protocol that provides an unreliable, unordered data delivery between devices connected to an IP network. It is generally considered a "layer 4" protocol in the OSI stack. One popular use of UDP is for transport of time-sensitive information, such as Voice over IP. UDP is specified in RFC 768.
http://www.techabulary.com/u/udp/
You either need to use TCP, or be prepared to handle the out-of-order (and possibly completely missing) responses.
SCTP is another option for your transmission protocol.
trying to send string data to windows c# application with this code;
try {
var ws = new WebSocket('ws://192.168.1.77:10048');
ws.onopen = function () {
ws.send("Sunucuya mesaj"); // I WANT TO SEND THIS MESSAGE TO SERVER!
};
ws.onclose = function () {
alert('Bağlantı kapandı.');
};
}
catch (e) {
alert(e);
}
and trying to get data from windows c# application with this code;
static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8181));
serverSocket.Listen(128);
serverSocket.BeginAccept(null, 0, OnAccept, null);
private static void OnAccept(IAsyncResult result)
{
byte[] buffer = new byte[1024];
try
{
Socket client = null;
string headerResponse = "";
if (serverSocket != null && serverSocket.IsBound)
{
client = serverSocket.EndAccept(result);
var i = client.Receive(buffer);
headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i);
// write received data to the console
Console.WriteLine(headerResponse);
}
if (client != null)
{
var key = headerResponse.Replace("ey:", "`")
.Split('`')[1] // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
.Replace("\r", "").Split('\n')[0] // dGhlIHNhbXBsZSBub25jZQ==
.Trim();
// key should now equal dGhlIHNhbXBsZSBub25jZQ==
var test1 = AcceptKey(ref key);
var newLine = "\r\n";
var response = "HTTP/1.1 101 Switching Protocols" + newLine
+ "Upgrade: websocket" + newLine
+ "Connection: Upgrade" + newLine
+ "Sec-WebSocket-Accept: " + test1 + newLine + newLine
//+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
//+ "Sec-WebSocket-Version: 13" + newLine
;
// which one should I use? none of them fires the onopen method
client.Send(System.Text.Encoding.UTF8.GetBytes(response));
var i = client.Receive(buffer); // wait for client to send a message
// once the message is received decode it in different formats
Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i));
Console.WriteLine("\n\nPress enter to send data to client");
Console.Read();
var subA = SubArray<byte>(buffer, 0, i);
client.Send(subA);
Thread.Sleep(10000);//wait for message to be send
}
}
catch (SocketException exception)
{
throw exception;
}
finally
{
if (serverSocket != null && serverSocket.IsBound)
{
serverSocket.BeginAccept(null, 0, OnAccept, null);
}
}
}
with this code i can communicate between client and server but i can't get ws.send("Sunucuya mesaj"); message from server that send from client. headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i); in this row you can see the header that is getting from server;
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.1.77:8181
Origin: http://localhost
Sec-WebSocket-Key: dHI34r7feV/Ar4G0/fONCg==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
How can i get data that is coming from client from server-side?
Thanks...
Messages between client and server are not plain text. See the data framing section of the protocol spec for details on how to encode/decode messages.
There are several liberally licensed open source C# servers you can take examples from. Such as Fleck
First of all, I'm absolutely not a network programmer. What I try to do, is a very simple TCP/IP communication between a Java server and a C# client.
Java server:
public void run(){
try {
// Open server socket
_server = new ServerSocket(SERVER_PORT);
_client = _server.accept();
System.out.println("ComInterface: client connected.");
// Wait for a client data output stream
while(true){
// Receive message from client
BufferedReader is =
new BufferedReader(new InputStreamReader(_client.getInputStream()));
msg = is.readLine();
// Process message
if(msg!=null){
System.out.println("ComInterface: Message Received : <" + msg + ">.");
processMessage(msg); // Independant method
}
else{
System.out.println("ComInterface: client closed connection.");
_client.close();
_client = _server.accept();
System.out.println("ComInterface: client connected.");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String msg){
try {
// Out stream
DataOutputStream os = new DataOutputStream(_client.getOutputStream());
os.writeBytes((String)(msg+"\n"+(char)13));
os.flush();
System.out.println("ComInterface: Message <" + msg + "> sent");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And here's the C# client:
public class ComInterface : MonoBehaviour
{
public const String SERVER_IP = "127.0.0.1"; // Localhost
public const int PORT = 1100; // Default port
public const int READ_BUFFER_SIZE = 5000; // 4.8828125 kilobytes
private TcpClient _client;
private ASCIIEncoding _asen;
private byte[] _readBuffer;
private String _msg;
public Boolean connected { get; internal set; } // setter is for internal use only
/**
* Initialize internal variables (buffer, socket...)
*/
public ComInterface()
{
connected = false;
_client = new TcpClient();
_asen = new ASCIIEncoding();
_readBuffer = new Byte[READ_BUFFER_SIZE];
_msg = String.Empty;
}
/**
* Connect to server at SERVER_IP:PORT
* Return true if connection was a success, or false if failure.
*/
public Boolean Connect()
{
try
{
_client.Connect(SERVER_IP, PORT);
connected = true;
Array.Clear(_readBuffer, 0, _readBuffer.Length);
Debug.Log("TCPClient: <Connect> Connected to the server");
// Start an asynchronous read invoking ReceiveComMessage
_client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _client.GetStream());
}
catch (Exception ex)
{
Debug.Log("TCPClient: <Connect> Cannot connect to the server - " + ex.Message);
connected = false;
}
// Return connection state
return connected;
}
/**
* Received a message from Communicator
*/
private void ReceiveComMessage(IAsyncResult ar)
{
int BytesRead;
String msg;
try
{
BytesRead = _client.GetStream().EndRead(ar);
if (BytesRead < 1)
{
// if no bytes were read server has close.
Debug.Log("TCPClient: <ReceiveComMessage> The server has closed (BytesRead<1)");
this.Disconnect();
return;
}
// Convert the byte array the message was saved into,
msg = Encoding.ASCII.GetString(_readBuffer);
Debug.Log("C# Message: \"" + msg + "\""); // Output example in log below
BytesRead = 0;
Array.Clear(_readBuffer, 0, _readBuffer.Length);
// Start a new asynchronous read into readBuffer.
_client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _readBuffer);
}
catch (Exception ex)
{
Debug.Log("TCPClient: <ReceiveComMessage> The server has closed (Exception):" + ex.Message + " see " + ex.StackTrace);
this.Disconnect();
}
The main problem is that all the message are arriving incomplete. Here's the log trace:
C#: Message "{
C#: Message ""sender":"Bob"",
C#: Message ""recipient":",
etc...
Instead of for instance
C#: Message "{"sender":"Bob","recipient":[1,2,3]}"
I'm a bit confused and I'd need some help to resolve this. Thank you very much!
TCP is a stream-oriented connection, not message-oriented. It has no concept of a message. When you write out your serialized string, it only sees a meaningless sequence of bytes. TCP is free to break up that stream up into multiple fragments and they will be received at the client in those fragment-sized chunks. It is up to you to reconstruct the entire message on the other end.
In your scenario, one would typically send a message length prefix. This way, the client first reads the length prefix so it can then know how large the incoming message is supposed to be.
I would seriously consider using something like Google's Protocol Buffers as a good way of declaring your messages and then streaming them with the size prefix option. The nice thing is that you define your set of messages once and then use the available tools to automatically generate C++, Java, C#, etc code from the message definitions. This will help in having a consistent messaging set that works between languages.
A message (any data, I mean), when sent through a socket, is divided into several packets.
When printing each received packet, you don't see your whole message.
You should define an end of message string (something like ".#."). Until you receive this sequence, you keep concatenating the messages you receive.
This is what session protocols (that is, protocols that run on the top of TCP) do.
Hope this helps.
Regards, Calil
Take a look at this example...
Java TCP Server...
import java.net.*;
import java.io.*;
public class TcpServer
{
public static void main(String h[])
{
try
{
ServerSocket serverSocket = new ServerSocket(1100);
Socket socket = serverSocket.accept();
System.out.println("Client Accepted");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Received: " + bufferedReader.readLine());
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
printWriter.println("Hello Theo. Welcome to socket programming.");
} catch (Exception e)
{
System.out.println(e);
}
}
}
C# TCP Client...
using System;
using System.IO;
using System.Net.Sockets;
class Program
{
static void Main(string[] args)
{
try
{
var client = new TcpClient("localhost", 1100);
var stream = client.GetStream();
var streamWriter = new StreamWriter(stream);
streamWriter.WriteLine("My name is Theo");
streamWriter.Flush();
var streamReader = new StreamReader(stream);
Console.WriteLine("Received: " + streamReader.ReadLine());
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Press a key to continue.");
Console.ReadKey();
}
}
my goal is to send simple text data and also complex data to client application using socket..this is some of my code
private void button1_Click(object sender, EventArgs e)
{
byte[] data;
data = Encoding.ASCII.GetBytes("Welcome!!!");
ns.Write(data, 0, data.Length);
ns.Flush();
List<Person> list = new List<Person>();
for (int a = 0; a < 5; a++)
{
Person person = new Person();
person.Name = textBox1.Text;
person.Age = int.Parse(textBox2.Text);
list.Add(person);
}
BinaryFormatter formatter = new BinaryFormatter();
for (int a = 0; a < 5; a++)
{
formatter.Serialize(ns, list[a]);
}
ns.Flush();
}
and at the client i write this code to add all data to listview
private void AddToListView()
{
while (true && ns.DataAvailable)
{
byte[] data = new byte[1024];
int recv;
recv = ns.Read(data, 0, data.Length);
textFromServer = Encoding.ASCII.GetString(data, 0, recv);
ns.Flush();
listView1.Items.Add(textFromServer);
temp = formatter.Deserialize(ns) as Person;
ns.Flush();
listView1.Items.Add(temp.Name);
listView1.Items.Add(temp.Age);
}
}
but when i debug the application,,nothing happens...if i delete the networkstream read() process,,the application run nicely..the problem is,i not only need to send the user object,,but also simple text to client..can someone help me please?
is it possible using networkstream.read() and binaryformatter.deserialize() at the same time??or,we have to choose one of it?
i mean when just to send/receive simple text,,we use networkstream.read()/write(),,and for complex object we use serialize/deserialize..is it possible??
The problem with what you are doing is that the server and client need to have an agreed upon protocol by which to send and receive data. For instance your Client code will read everything that is available in the first ns.Read call you make. There is nothing that signals the end of one type of data and the beginning of the next, and thus you don't have an agreed upon method by which you are sending/reading data.
Easiest might be for you to encapsulate the data into another object that can contain both strings and objects.
[Serializable]
public class EncapsulatedData{
public EncapsulatedData(){}
public string Message{ get; set; }
public ISerializable Object{ get; set; }
}
And you will set Object to be a ISerializable type of yours, such as Person. Then you should be able to deserialize on the client and check Message or Object.
There are cleaner ways to do this, but the above trick should work for you.
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ClientServer
{
class ClientServerProgram
{
public static void SendHeader(string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
{
String sBuffer = "";
// if Mime type is not provided set default to text/html
if (sMIMEHeader.Length == 0)
{
sMIMEHeader = "text/html"; // Default Mime Type is text/html
}
sBuffer = sBuffer + "HTTP/1.1" + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: cx1193719-b\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
mySocket.Send(Encoding.ASCII.GetBytes(sBuffer),Encoding.ASCII.GetBytes(sBuffer).Length, 0);
Console.WriteLine("Total Bytes : " + iTotBytes.ToString());
}
public static void ReceiveCallback(IAsyncResult AsyncCall)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
string messageString = "I am a little busy, come back later!";
Byte[] message = encoding.GetBytes(messageString);
Socket listener = (Socket)AsyncCall.AsyncState;
Socket client = listener.EndAccept(AsyncCall);
Console.WriteLine("Received Connection from {0}", client.RemoteEndPoint);
SendHeader("text/html", message.Length, "202 OK", ref client);
client.Send(message);
Console.WriteLine("Ending the connection");
client.Close();
listener.BeginAccept(new AsyncCallback(ReceiveCallback), listener);
}
public static void Main()
{
IPAddress localAddress = IPAddress.Parse("192.0.127.1");
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 8080);
listenSocket.Bind(ipEndpoint);
listenSocket.Listen(1);
listenSocket.BeginAccept(new AsyncCallback(ReceiveCallback), listenSocket);
while (true)
{
Console.WriteLine("Waiting....");
Thread.Sleep(1000);
}
}
}