So, i am trying to make a c++ WinSock2 chatter, just for learning. It is a console application and i want to take user input (for sending to the counterpart), but i still want to be able to recive. (so you can write a message while still being able to recive one)...
When using cin >> input;
the program "pauses" until the user has enterd something, that way it is "turn based" (one user writes something and sends it, then the other user writes something and sends it).
Is there a way to make the user be able to write something WHILE the recive stuff is still running? (Preferably something else than multi threading)
What about checking if buffer isn't empty? But code wouldn't be really portable then, because you need to make some system calls as I know. See this.
But maybe you can do it with some C code, I'll do some research and update my answer.
UPD: Ok, I did it. What you need is select function.
It could wait till
stdin
is ready for read, and that's what we need. But looks like it don't work with C++ streams, so you need to use only C code for reading.Let's jump to definition:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
Ok, we need to check only read buffer, so
writefds
anderrorfds
could beNULL
. And we need to check onlystdin
, sonfds
is1
(number offds
es)What about timeout? It's should be
0
, so we need to initialize variablestruct timeval timeout
and set seconds and nanoseconds to 0 bytimeout.tv_sec = 0
andtimeout.tv_usec = 0
.So, only
readfds
left. It's pretty simple too: we need to initialize variable, "zero" it, and addstdin
.It can be done with
fd_set readfds
,FD_ZERO(&readfds)
andFD_SET(STDIN_FILENO, &readfds)
.Okay, final step: function call. It should be
select(1, &readfds, NULL, NULL, &timeout)
.This would return
0
if input buffer is empty and1
if it's not.UPD2: Looks like it's not C++ streams, something strange happens and it breaks when buffer is empty at very first call. I'll try to catch the problem.
UPD3: Ok, Now I figured it out. Looks like you can use
select
with C++ streams.Select
has VERY strange (IMHO) feature: it resetsreadfds
. I'm not sure how to prevent It from doing this, so I just used one morefd_set
variable to hold it, so you need to addfd_set savefds = readfds
afterreadfds
initialization, andreadfds = savefds
after each call. That's awful solution, but I don't know how could I improve it.So code is:
Initialization:
Timeout initialization:
And usage:
UPD4: Don't forget to include
unistd.h
andcstdlib