Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Back and forth and closing.  (Read 4078 times)

0 Members and 1 Guest are viewing this topic.

vEjEsE

  • Newbie
  • *
  • Posts: 28
    • View Profile
Back and forth and closing.
« on: February 03, 2011, 07:04:49 pm »
Trying to make a console chat system on which to test my networking skills. I'm going with TCP for now. The chat system isn't much of a problem. The only things I'm having trouble with is server sending data to clients and shutting down the server/client.

The server checks for incomming connection and incoming packeges, like in the tutorial. The client sends packeges to the server.

This is a function with which the chat system gets messages over the internet:
Code: [Select]

while ( m_Open ) {
nw::Network::packetVec Packets = nw::NetworkAccessor::GetNetwork()->ReceiveData();

for ( nw::Network::packetVec::iterator it = Packets.begin(), itEnd = Packets.end(); it != itEnd; ++it ) {
std::string Message;
(*it) >> Message;

m_Mutex.Lock();
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coords);
std::cout << "                                             ";
etConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coords);
std::cout << Message;
m_Mutex.Unlock();

if ( Coords.Y < 31 )
++Coords.Y;
else
Coords.Y = 11;
}
}

Packets is a vector of sf::Packet (in case you are the server and receive several packeges a time).

Here's the Receive function for client:
Code: [Select]

nw::Network::packetVec nw::Client::ReceiveData() {

nw::Network::packetVec Packets;

sf::Packet Packet;
if ( m_Socket.Receive(Packet) == sf::Socket::Done ) {
Packets.push_back(Packet);
}
else {
std::string Message = "An error occured.";
Packet << Message;
Packets.push_back(Packet);
}


return Packets;
}

There's only one packet because there's only one socket. (One packet at a time).

The Receive function is the function that receives packets - calling the Wait function on the selector - if server, or calling the receive function on the socket - if client (both are blocking so it's the same). And as soon as a packege (or more if you are server) arrive, it will receive it and continue with the while (m_Open) loop.
The problem is that this loop only loops if there is an incoming packege, which is fine because I don't want it to loop like crazy if there's nothing to process. But now the program only closes if - after I hit Q for close - someone sends a packet to me. Which is stupid. (I know, I did it this way.)
So I was wondering if I'm client, doing "Socket.Close()" will close the socket and the Receive funtion ends so the loop continues with Packets size 0 and break? Or that won't help at all, maybe even breaking stuff?

As for server side - clearing the selector will make the Wait function return? Maybe even closing the listening socket...
All this done with threads.


And the last part.
All the clients that are connected to the server have a socket in the selector. How can I use them to send from the server to the clients? I can't acces them in the selector. Or I need an additional socket to connect to the client, doing some sort of server-server stuff?

Ok, I think the post is long enough. Let me know if I know something wrong, or doing wrong, or just wrong.
And sorry for my bad English...
And sorry if this is already posted somewhere else. I haven't found anything specific, or I'm bad at searching.

Thanks for reading.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Back and forth and closing.
« Reply #1 on: February 03, 2011, 07:10:50 pm »
Quote
So I was wondering if I'm client, doing "Socket.Close()" will close the socket and the Receive funtion ends so the loop continues with Packets size 0 and break? Or that won't help at all, maybe even breaking stuff?

I'm not sure (depends on how the low-level behaves), but don't think it help to Close() while the socket is Receive()ing. It could even crash -- or work, you should test :)

Quote
As for server side - clearing the selector will make the Wait function return? Maybe even closing the listening socket...
All this done with threads.

Nop, clearing a selector while it's waiting won't stop it.

Quote
All the clients that are connected to the server have a socket in the selector. How can I use them to send from the server to the clients? I can't acces them in the selector. Or I need an additional socket to connect to the client, doing some sort of server-server stuff?

Selector is not a container, if you want to loop over all your clients sockets you must store them in your own container.
Laurent Gomila - SFML developer

vEjEsE

  • Newbie
  • *
  • Posts: 28
    • View Profile
Back and forth and closing.
« Reply #2 on: February 03, 2011, 07:20:21 pm »
Thanks for the fast reply.

I can't think of anything else then Close() for breaking out of the loop.
Or unblocking the receive/send functions but then it will loop even if there's nothing to process.

OR! Maybe...
If the client disconnects, it sends a packege to the server, letting it know, then the server sends a packege back - the Receive function returns and the loop breaks.
But how would the server do that? Send himself a packege... funny.


About the costum container for sending to the clients:
I can make a container of sockets, and if there is a new connection:
Code: [Select]

Socket = Selector.Wait();
if ( Socket == Listener ) {
    // accept
    // add in selector
    m_ClientSockets.insert(Socket);
}

Now I can
Code: [Select]

for ( loop thru m_ClientSockets )
    m_ClientSocket[i].Send(Packet);

?

Can a socket send while it is receiving? Or it's not the same socket...? (since I copy it)

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
Back and forth and closing.
« Reply #3 on: March 31, 2011, 01:35:33 am »
Quote from: "vEjEsE"
Can a socket send while it is receiving? ... (since I copy it)

I'm going to be trying to do this in my multithreaded application. I searched the forums first to see if it was possible, but all I found was this thread without an answer.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Back and forth and closing.
« Reply #4 on: March 31, 2011, 07:54:59 am »
That's right, nobody (including me) could answered this question.

It should be ok but I could never find a clear answer in the docs.
Laurent Gomila - SFML developer

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
Back and forth and closing.
« Reply #5 on: April 06, 2011, 11:23:19 pm »
As an update for closure, I was able to send while receiving using TCP, but using UDP, I couldn't send while the socket was bound.

So, at least on Windows, two sockets need to be made when using UDP: one for sending and one for receiving.

Edit: Nevermind. As far as I can tell, both can send while receiving.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Back and forth and closing.
« Reply #6 on: April 07, 2011, 01:52:51 am »
That's not quite true, since both TCP and UDP sockets are bidirectional. Can you provide a minimal example, please?