How can I accept multiple clients?
I want to write my own http server using
TCP
and System.Net.Sockets
. Here is my code:
How can I accept multiple sockets? Should I create new Thread
for each socket (I'll add while loop later)? Also, should I store threads somewhere to finish them after I handled request? Maybe you can give any other advices on this topic15 Replies
you are already using asyc/await, so there shouldn't be the need to create threads
maybe a little more error control would be nice
(also, in case, there is an implementation of http web server in the framework)
to handle multiple clients at the same time u would in a loop await a new connection and spawn but not await a new task that handles that single connection
on another note u have issues regarding receiving and sending, its not guaranteed that u receive/send the whole message at once.
eg for sending:
payload
has a length of 11, but it could also be that it couldnt send all bytes and thus bytesSent
is less than 11i mean he's not really using the data
(for now?)
now assume the client sends
hello world
, it could be that with that first ReceiveAsync()
call u only receive hell
and the rest would require more calls to ReceiveAsync()
to get the rest.
well, they are reading and decoding the byte array to utf8, so even there it could throw an exception because of an invalid byte sequence, if that is teared apart because the full message wasnt received by one call to ReceiveAsync()
(and a little side note: Content - Type
is wrong, header names are without whitespaces, this should be Content-Type
)especially because http is a protocol where u dont have any size prefix, its not an easy to implement protocol, due to not knowing beforehand how much u have to read.
System.IO.Pipelines helps a lot to manage those teared reads/writes
I/O pipelines - .NET
Learn how to efficiently use I/O pipelines in .NET and avoid problems in your code.
it could also simply be that the http request is longer than the buffer size u r using, another problem ⤴️ is solving
Thank you I'll read it
I want to implement both json and html (templates) routes, I'll do more complex error control
I have a question, how do I know when client sent all the data (regual data or file)? I tried to do while loop (receivedBytes > 0), but loop never finishes (that's how it is done in c++ example).
u have to read about how the http request is structured. if u receive 0 bytes, this means that the connection was closed by the peer
the rough structure for requests is
- first line: request method and resource and http version (eg.
GET /index.html HTTP/1.1
)
- optional headers (eg Host: example.org
)
- empty line
- optional request body
all line breaks have to be CRLF ("\r\n"
)
if there is one, to determine request body length/content u need to look at the headers, there could be a simple Content-Length
header telling u how many bytes the request body has, but there is also a chunk based encoding
so for example
https://www.tutorialspoint.com/http/index.htm seems to have some good resources
HTTP Tutorial
HTTP Tutorial - The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems. This is the foundation for data communication for the World Wide Web (i.e. internet) since 1990. HTTP is a generic and stateless protocol which can be used for othe
the loop never finishes because the connection is still open and ther could be other data
you have to parse the message and understand its structure
because tcp doesn't have feature of "sending a message" (which would be a self-contained amount of data), it just transmits unstructured data
okay, thank you
i would also recommend to sticking to http 1.1 for now, http 2 is vastly more complex
or even http 1.0 (maybe http 0.9 would be too much)
Yes, I will, I already have a lot of things to think about besides parsing, I want to make something similar to asp.net minimal api
but also add template engine
well, the actual http message stuff is mostly the same between 1.1 and 2, but 2 comes with multiplexing multiple requests via one tcp connection and thats the most complex part (and the prerequisite of ssl/tls)