I am writing two console applications, a client and a server.
I'm a little stuck at two things, which seemed rather easy at first..
#1: I want to write a function for the following piece of code, that converts bits to a string, but I cant just figure it out. The server always crashes when I use it. My function is a little bit different than this one, but that's because my current code has to include the connection information, and I think there's a better way to do it:
byte[] b = new byte[100];
int k = s.Receive(b);
string packet = null;
for (int i = 0; i < k; i++)
{
Console.Write(Convert.ToChar(b[i]));
packet = packet + Convert.ToChar(b[i]);
}
I guess the function is not the problem, but how I use it is. Any help would be very much apreciated.
Edit:
I am calling and using it like this:
byte[] b = new byte[100];
string response = BitConvert(b);
if (response == "Hi there")
#2 I want the client to álways send a packet just once, with a password. And if that password doesn't match the password mentioned as a string in the server, it should close the connection with the client.
I know how to send the packet just once, but I don't know how to check the packet in the server just once for each client.
Or in other words, at the moment the server has no way of knowing if the client has already been authenticated. So I guess the client needs to have some sort of socket ID, and the server needs a table with the ID, and a boolean to see if it's autenticated or not.
The first part, getting the bytes into a string ... how about:
byte b[] = new byte[100];
int k = s.Receive(b, b.Length, 0);
string packet = Encoding.ASCII.getString(b, 0, k);
Part 2 ... not sure off the top of my head.
I'm with Rob above on part 1 and as for part 2...
Assuming you're using a TCP connection the System.Net.Sockets class should handle your
needs.
If you use either AcceptSocket or AcceptTcpClient to pull a connection from the incoming connection request queue you'll get a socket or tcpclient that is unique to that connection. simply leave it open until you're done with it. (There are also non-blocking alternatives if your service has other things to do...)
If the client closes it or opens up a new connection the will have to reauthenticate somehow. (This may be by including a token that you generate for them when they first authenticate - that's your only option if you're using UDP connections).
Related
This question already has an answer here:
C# TcpClient: Send serialized objects using separators?
(1 answer)
Closed 4 years ago.
Being a "novice" in C# and C# Network programming I tried to make a simple chat in C# using TCPClient and TCPListener , I've managed to send data from client to server but if I add a second client the server doesnt read his data and i have a second issue I couldn't figure out how to send data from server to client using TCPListener .
Server :
while (true)
{
Socket client = Server.AcceptSocket();
Console.WriteLine("Connection accepted from " + client.RemoteEndPoint);
count += 1;
string msg;
byte[] buf = new byte[1024];
client.Receive(buf);
msg = Encoding.UTF8.GetString(buf);
Console.WriteLine("Received... " + msg + "");
}
}
Client :
while (true)
{
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String msg = Console.ReadLine();
Stream stm = tcpClient.GetStream();
ASCIIEncoding asen= new ASCIIEncoding();
byte[] send = asen.GetBytes(msg);
Console.WriteLine("Transmitting.....");
stm.Write(send, 0, send.Length);
if (msg == "/Q"){
tcpClient.Close();
Environment.Exit(0);
}
}
If you see any absurdity / Mistake in my code please tell me i'm here to learn !
Thank You
Where I am not the best with C# this post Server Client send/receive simple text how to create C# simple server, and should fix the first issue of the client not being able to recive data from the server.
As for the second issue not being able to support mulitple connections, this could be to do with there is no threading, so the question is do you want to create a C# webserver or a C# application which utilizes TCP communication to a server.
if the answer is the latter, then I would look to installing tried and tested server such a Apache or Nginx. this will allow the server to handle multiple requests on your behalf and skip having to handle multiple connections and threads, while you are learning more about the client server relationship. also this article may help setting up the fastcgi environment for the appliction http://www.mono-project.com/docs/web/fastcgi/nginx/
otherwise then you will have to look at how to handle multiple clients which this post looks like it could help TCP server with multiple Clients
I have a huge problem. I write small servers in C#. My clients are JavaScript. JavaScript use HTTP GET to communicate because JavaScript must pass Same Origin Policy. It means I must use HTTP GET to comunication. Now I notice that C# cut (??) my URL.
I sended:
http://172.16.210.25:8000/?callback=ProxyApi.saveStat&cid=1343823765156_495&cidget=null&s[901]=1044!:!5878849%3B6658291%3B2964823%3B1178767%3B469747%3B481939%3B6431323%3B1032649%3B2750603%3B208057%3B9192763%3B6669071%3B2014351%3B6816157%3B3784367%3B1242929%3B4488073%3B7662331%3B2991731%3B6404357%3B8248091%3B1795603%3B4880191%3B3080303%3B4093847%3B4618063%3B7501937%3B2842849%3B6953249%3B7102679%3B5667853%3B9851873%3B5517823%3B6114539%3B6061597%3B7647599%3B4871873%3B400087%3B7514713%3B3958217%3B8163713%3B9560437%3B8229701%3B3408749%3B4432097%3B3353219%3B2936693%3B1343597%3B3490451%3B1266191%3B9125747%3B6152921%3B2689537%3B3796861%3B4987009%3B1206841%3B9278119%3B9499619%3B455627%3B6217051%3B7603201%3B8019079%3B5306033%3B8314939%3B2997221%3B3996221%3B3889649%3B1148507%3B9397139%3B4984949%3B6576473%3B3993247%3B676051%3B5%3B&s[902]=929!:!9012569%3B9836633%3B5239051%3B6102559%3B5944079%3B9749681%3B4007797%3B344821%3B9914917%3B1950227%3B982847%3B6610337%3B6734281%3B4213463%3B1620449%3B1745111%3B8005717%3B6740443%3B8290811%3B9652289%3B279557%3B9077213%3B169933%3B4785463%3B368521%3B5881487%3B5735711%3B189377%3B3417091%3B8616299%3B7168723%3B4220969%3B4493651%3B5067977%3B1646387%3B3925297%3B5990723%3B6826471%3B3040753%3B1449733%3B8905681%3B2502001%3B7304107%3B1022677%3B4966529%3B8679397%3B4319519%3B3991279%3B1128641%3B2148631%3B2215987%3B1135217%3B3846281%3B1049843%3B309937%3B2241691%3B8768581%3B6199693%3B7973921%3B9683627%3B9664957%3B4493023%3B2494729%3B3581167%3B8474597%3B1987919%3B6099271%3B&t=68999&pxid=142221422
But I got in string:
?callback=ProxyApi.saveStat&cid=1343823765156_495&cidget=null&s[901]=1044!:!5878849%3B6658291%3B2964823%3B1178767%3B469747%3B481939%3B6431323%3B1032649%3B2750603%3B208057%3B9192763%3B6669071%3B2014351%3B6816157%3B3784367%3B1242929%3B4488073%3B7662331%3B2991731%3B6404357%3B8248091%3B1795603%3B4880191%3B3080303%3B4093847%3B4618063%3B7501937%3B2842849%3B6953249%3B7102679%3B5667853%3B9851873%3B5517823%3B6114539%3B6061597%3B7647599%3B4871873%3B400087%3B7514713%3B3958217%3B8163713%3B9560437%3B8229701%3B3408749%3B4432097%3B3353219%3B2936693%3B1343597%3B3490451%3B1266191%3B9125747%3B6152921%3B2689537%3B3796861%3B4987009%3B1206841%3B9278119%3B9499619%3B455627%3B6217051%3B7603201%3B8019079%3B5306033%3B8314939%3B2997221%3B3996221%3B3889649%3B1148507%3B9397139%3B4984949%3B6576473%3B3993247%3B676051%3B5%3B&s[902]=929!:!9012569%3B9836633%3B5239051%3B6102559%3B5944079%3B9749681%3B4007797%3B344821%3B9914917%3B1950227%3B982847%3B6610337%3B6734281%3B4213463%3B1620449%3B1745111%3B8005717%3B6740443%3B8290811%3B9652289%3B279
I lost some important data.
Im listing using:
IPAddress local_ip = Dns.GetHostAddresses(Dns.GetHostName())[0];
TcpListener sockServer = new TcpListener(local_ip,Port);
sockServer.Start();
And
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunction), sockServer.AcceptSocket());
And inside ThreadFunction I have
static void ThreadFunction(Object param)
{
Socket socket = (Socket)param;
proxy.Run(socket);
}
Finally I read message using this:
int bytes = ReadMessage(socket, readBuf, ref strFromClient);
Can you help me pass problem with URL LENGHT or change method of listining (unknown Javscript clients send large messeage using HTTP GET.)
===================
EDIT
I try using IE, Chrome and FF. I sent
http://172.16.210.25:8000/?callback=ProxyApi.saveStat&cid=1343823765156_495&cidget=null&s[901]=1044!:!5878849%3B6658291%3B2964823%3B1178767%3B469747%3B481939%3B6431323%3B1032649%3B2750603%3B208057%3B9192763%3B6669071%3B2014351%3B6816157%3B3784367%3B1242929%3B4488073%3B7662331%3B2991731%3B6404357%3B8248091%3B1795603%3B4880191%3B3080303%3B4093847%3B4618063%3B7501937%3B2842849%3B6953249%3B7102679%3B5667853%3B9851873%3B5517823%3B6114539%3B6061597%3B7647599%3B4871873%3B400087%3B7514713%3B3958217%3B8163713%3B9560437%3B8229701%3B3408749%3B4432097%3B3353219%3B2936693%3B1343597%3B3490451%3B1266191%3B9125747%3B6152921%3B2689537%3B3796861%3B4987009%3B1206841%3B9278119%3B9499619%3B455627%3B6217051%3B7603201%3B8019079%3B5306033%3B8314939%3B2997221%3B3996221%3B3889649%3B1148507%3B9397139%3B4984949%3B6576473%3B3993247%3B676051%3B5%3B&s[902]=929!:!9012569%3B9836633%3B5239051%3B6102559%3B5944079%3B9749681%3B4007797%3B344821%3B9914917%3B1950227%3B982847%3B6610337%3B6734281%3B4213463%3B1620449%3B1745111%3B8005717%3B6740443%3B8290811%3B9652289%3B279557%3B9077213%3B169933%3B4785463%3B368521%3B5881487%3B5735711%3B189377%3B3417091%3B8616299%3B7168723%3B4220969%3B4493651%3B5067977%3B1646387%3B3925297%3B5990723%3B6826471%3B3040753%3B1449733%3B8905681%3B2502001%3B7304107%3B1022677%3B4966529%3B8679397%3B4319519%3B3991279%3B1128641%3B2148631%3B2215987%3B1135217%3B3846281%3B1049843%3B309937%3B2241691%3B8768581%3B6199693%3B7973921%3B9683627%3B9664957%3B4493023%3B2494729%3B3581167%3B8474597%3B1987919%3B6099271%3B&t=68999&pxid=142221422
But I always get
GET /?callback=ProxyApi.saveStat&cid=1343823765156_495&cidget=null&s[901]=1044!:!5878849%3B6658291%3B2964823%3B1178767%3B469747%3B481939%3B6431323%3B1032649%3B2750603%3B208057%3B9192763%3B6669071%3B2014351%3B6816157%3B3784367%3B1242929%3B4488073%3B7662331%3B2991731%3B6404357%3B8248091%3B1795603%3B4880191%3B3080303%3B4093847%3B4618063%3B7501937%3B2842849%3B6953249%3B7102679%3B5667853%3B9851873%3B5517823%3B6114539%3B6061597%3B7647599%3B4871873%3B400087%3B7514713%3B3958217%3B8163713%3B9560437%3B8229701%3B3408749%3B4432097%3B3353219%3B2936693%3B1343597%3B3490451%3B1266191%3B9125747%3B6152921%3B2689537%3B3796861%3B4987009%3B1206841%3B9278119%3B9499619%3B455627%3B6217051%3B7603201%3B8019079%3B5306033%3B8314939%3B2997221%3B3996221%3B3889649%3B1148507%3B9397139%3B4984949%3B6576473%3B3993247%3B676051%3B5%3B&s[902]=929!:!9012569%3B9836633%3B5239051%3B6102559%3B5944079%3B9749681%3B4007797%3B344821%3B9914917%3B1950227%3B982847%3B6610337%3B6734281%3B4213463%3B1620449%3B1745111%3B8005717%3B6740443%3B8290811%3B9652289%3B279
Look
private Byte[] readBuf = new Byte[2048];
int bytes = ReadMessage(socket, readBuf, ref strFromClient);
My bytes always are to 1024. Where can be limits of there?
HTTP GET requests are usually limited to ~2000 characters (client-wise, that is)
Here's a reference from MS
GET is not intended for sending large amount of data, that's why it's called GET... try to provide more information regarding your client and we might be able to offer you an alternative
I was careless.
Function ReadMessage is function from own class. And it wrote:
sock.Receive(buf, 1024, 0);
Of course I fix:
sock.Receive(buf,buf.Length,0);
And Now it runs.
Thank for your answers.
I'm trying to send a broadcast UDP message to a C# application. I have tried the following code to send the message. Which I found on the php.net website as a comment to the socket_sendto manual page.
<?php
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1);
socket_sendto($sock, $broadcast_string, strlen($broadcast_string), 0, '255.255.255.255', $port);
?>
This doesn't work for me, maybe it's my network.
But it does work if I replace the broadcast IP '255.255.255.255' to my specific IP e.g. '192.168.1.128'. I can see this message coming in with Wireshark, while I can't see this using the above code. This leads me to believe there is something wrong with the PHP side of the code. I really want to use broadcasting or some kind of multicasting for my program, so I'm a bit stuck at the moment ;)
I use the following on the (C#) receiving end (for testing):
UdpClient subscriber = new UdpClient(15000);
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 15000); ;
byte[] pdata = subscriber.Receive(ref ep);
string data = Encoding.ASCII.GetString(pdata);
MessageBox.Show(data);
subscriber.Close();
Any idea what could be the cause of this?
Try specifying the MSG_DONTROUTE flag in your script. Taking inspiration from this CodeGuru post, if this isn't specified the routers make the decision on whether or not to broadcast your message.
socket_sendto($sock, $broadcast_string, strlen($broadcast_string), MSG_DONTROUTE, '255.255.255.255', $port);
255.255.255.255 is a "limited" broadcast whereas your 192.168.1.255 is a "directed" broadcast.
Limited in simple terms means that it is only send within the LAN. LAN as defined by directly connected hosts, i.e. with no router in between. Routers--with a few exceptions--do not pass a limited broadcast but a directed broadcast.
Now, with your initial problem and question, I can only guess that you are sending your broadcast across a router.
I am writing a proxy application for iSCSI to do some diagnostic work (think Fiddler for iSCSI) - I'm trying to capture data one packet at a time, I don't want to read arbitrary sizes and end up getting all of one iSCSI packet and half of another - I really want to see the same kind of data as Wireshark would display for example. In doing this, I'm using Socket.ReceiveMessageFrom().
However, one of the parameters is called "endpoint", and I'm not quite sure what to do with it. Any clues? Here's my code, can you tell me if I'm completely off base:
Tuple<byte[], int> readOnePacket(TcpClient conn) {
var flags = SocketFlags.None;
EndPoint endpoint = null; /*** You can't set this to null!! ***/
byte[] buffer = new byte[10 * 0x100000];
int offset = 0;
int bytes_received;
do {
IPPacketInformation packet_information;
bytes_received = conn.Client.ReceiveMessageFrom(buffer, offset, BufferSize,
ref flags, ref endpoint, out packet_information);
if (flags == SocketFlags.Partial) {
// We only want to transfer full packets
offset = bytes_received;
continue;
}
} while (false);
return new Tuple<byte[], int>(buffer, bytes_received + offset );
}
It is not TcpClient.ReceiveMessageFrom(), but Socket.ReceiveMessageFrom()
If you take a look at the documentation, you will read the following:
An EndPoint, passed by reference, that
represents the remote server.
Edit:
Setting it to null is, indeed, a bad idea.
While not a direct answer to your question, I think this answer can still be useful (though lots of time passed since the question was asked).
Because I don't know if iSCSI works over TCP or over plain IP, I cannot offer a solution for your problem. But in general, TCP is a stream-oriented protocol, and doesn't have a notion of "message". On the other hand, IP is a datagram (i.e. message) oriented protocol, and it has notion of message. In your code, you're trying to read a "message" (IP construct) from TCP socket, and that will not work. Yes, TCP is based on IP, but IP datagrams are not visible on TCP level.
The problem you've mentioned (read full message, without reading into the next one) is applicable to TCP level only, because on IP you really can read one whole message. When you want the same thing on TCP level, you need to use a protocol with message support. Usually to achieve this you need to have you own protocol, based on TCP, with messages like this:
[msg header][msg body]
where [msg header] consists of something like:
[msg type][msg body length]
Msg type and msg body length have fixed length (say, 2 bytes for msg type and 4 bytes for body length), and msg body can have variable length, so you can read full header, then determine how long the body is, and based on that read full body.
Hope this helps.
I'm writing an application to send data over a network, and need to know if it is possible to set the Type of Service (ToS) bits in the IP Packet header. Anyone know if this is supported by C#, and if so how I should go about implementing it?
I know I can use a raw socket type and specify my own header, but I'd rather not have to do this as I'm only using TCP, so it seems a bit pointless to create an entire header just so I can set three bits, when it can be automatically created without these bits set.
Any suggestions would be greatly appreciated.
Wouldn't this work? (almost straight from TcpClient.Client help)
TcpClient client = new TcpClient();
Socket s = client.Client;
if (!s.Connected)
{
s.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.TypeOfService, 2);
}
Not sure what value you want to set it to, but this should work...