I usually create a client program simulating one session with the server, find as many linux boxes nearby and spin up a thousand of them on each machine from a command line like:
for i in {0..1000} ; ./myprogram serverip & done
In some cases the protocol is text based and the interaction or test is simple, so I don't have to write myprogram
but just use netcat, as in running nc serverip < input >/dev/null
If all you need is to test streaming data to your client, I'd start with netcat and work my way from there.
This approach is ok for my needs, I usually don't need to test more concurrency than a handful of thousand clients. If you need more scalability, you'll likely have to write the client simulator using io multiplexing (epoll) as well, having each instance simulate as much interactions as you can - and you'll have to do more controlled tests to find limits of your client .
Don't mix performance testing with functional testing though. While you might get awsome performance in a test environment, a live environment can be very different. e.g. clients will misbehave, they will disconnect at the most inapproriate of times. They might send you malicious data. They might be slow, leading to buildup of internal queues on the server or leving you with thousands of seemingly idle connections (killall -STOP nc
while in the middle of sending data to test clients might show you interresting things)