Reputation: 721
My goal is to create a user-server connection. Most importantly I'm not willing to use threads.
For now, I want it to work as a simple chat. I believe The issue is that It goes from one user to another in a loop waiting for their getline
input, so technically only one user can send a message at a time. What I wish is that my code could handle multiple messages from one user continuously, not having to wait for all other users to send a message
That's the running loop inside the server:
while (running)
{
fd_set copy = master;
// See who's talking to us
int socketCount = select(0, ©, nullptr, nullptr, nullptr);
// Loop through all the current connections / potential connect
for (int i = 0; i < socketCount; i++)
{
// Makes things easy for us doing this assignment
SOCKET sock = copy.fd_array[i];
// Is it an inbound communication?
if (sock == listening)
{
// Accept a new connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientsocket = accept(listening, (sockaddr*)&client, &clientSize);
// Add the new connection to the list of connected clients
FD_SET(clientsocket, &master);
// Send a welcome message to the connected client
string welcomeMsg = "Welcome to the Awesome Chat Server!\r\n";
send(clientsocket, welcomeMsg.c_str(), welcomeMsg.size() + 1, 0);
}
else // It's an inbound message
{
char buf[4096];
ZeroMemory(buf, 4096);
// Receive message
int bytesIn = recv(sock, buf, 4096, 0);
if (bytesIn <= 0)
{
// Drop the client
closesocket(sock);
FD_CLR(sock, &master);
}
else
{
// Send message to other clients, and definiately NOT the listening socket
for (int i = 0; i < master.fd_count; i++)
{
SOCKET outSock = master.fd_array[i];
if (outSock != listening && outSock != sock)
{
ostringstream ss;
ss << "SOCKET #" << sock << ": " << buf << "\r\n";
string strOut = ss.str();
send(outSock, strOut.c_str(), strOut.size() + 1, 0);
}
}
}
}
}
}
I belive this code should work, the issue is in my client code:
char buf[4096];
string userInput;
do
{
// Prompt the user for some text
cout << "> ";
getline(cin, userInput); //THATS THE ISSUE, IT WAITS FOR GETLINE
if (userInput.size() > 0) // Make sure the user has typed in something
{
// Send the text
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
// Wait for response
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
// Echo response to console
cout << "SERVER> " << string(buf, 0, bytesReceived) << endl;
}
}
}
} while (userInput.size() > 0);
My question is if its really caused by getline and if so, how can it be fixed?
Upvotes: 0
Views: 378
Reputation: 902
The answer to your question is "yes," but with a big proviso: a properly designed server shouldn't care what the client is doing. You might want to look into select() or, if you anticipate a large user community, poll(). You don't want a multi-user server to depend on/wait for a single client.
Upvotes: 1