【发布时间】:2013-02-04 12:42:34
【问题描述】:
我将一个数据包作为客户端发送到服务器,我希望服务器将该数据包转发给所有客户端,代码如下:
#include <iostream>
#include <SFML/Network.hpp>
using namespace std;
int main()
{
int fromID; // receive data from 'fromID'
int Message; // fromID's message
sf::SocketTCP Listener;
if (!Listener.Listen(4567))
return 1;
// Create a selector for handling several sockets (the listener + the socket associated to each client)
sf::SelectorTCP Selector;
Selector.Add(Listener);
while (true)
{
unsigned int NbSockets = Selector.Wait();
for (unsigned int i = 0; i < NbSockets; ++i)
{
// Get the current socket
sf::SocketTCP Socket = Selector.GetSocketReady(i);
if (Socket == Listener)
{
// If the listening socket is ready, it means that we can accept a new connection
sf::IPAddress Address;
sf::SocketTCP Client;
Listener.Accept(Client, &Address);
cout << "Client connected ! (" << Address << ")" << endl;
// Add it to the selector
Selector.Add(Client);
}
else
{
// Else, it is a client socket so we can read the data he sent
sf::Packet Packet;
if (Socket.Receive(Packet) == sf::Socket::Done)
{
// Extract the message and display it
Packet >> Message;
Packet >> fromID;
cout << Message << " From: " << fromID << endl;
//send the message to all clients
for(unsigned int j = 0; j < NbSockets; ++j)
{
sf::SocketTCP Socket2 = Selector.GetSocketReady(j);
sf::Packet SendPacket;
SendPacket << Message;
if(Socket2.Send(SendPacket) != sf::Socket::Done)
cout << "Error sending message to all clients" << endl;
}
}
else
{
// Error : we'd better remove the socket from the selector
Selector.Remove(Socket);
}
}
}
}
return 0;
}
客户端代码: 在 Player 类中我有这个功能:
void Player::ReceiveData()
{
int mess;
sf::Packet Packet;
if(Client.Receive(Packet) == sf::Socket::Done)
{
Client.Receive(Packet);
Packet >> mess;
cout << mess << endl;
}
}
main.cpp:
Player player;
player.Initialize();
player.LoadContent();
player.Connect();
..
..
//GAME LOOP
while(running==true)
{
sf::Event Event;
while(..) // EVENT LOOP
{
...
}
player.Update(Window);
player.ReceiveData();
player.Draw(Window);
}
当我运行此客户端代码时,程序没有响应,冻结。 问题在于 ReceiveDate() 函数。
【问题讨论】:
-
你确定不是服务器的问题吗?在调试器中运行并在接收消息的位置设置断点,然后逐行执行代码以查看会发生什么。
-
服务器在其他电脑上运行,只有客户端死机。所以..这是一个游戏,客户端不会冻结,直到我按下某个按钮,但只出现白屏,因为 player.ReceiveData() 正在运行,直到我收到一个数据包或什么?我不明白..
-
记住套接字默认是阻塞的。这意味着
Receive调用将阻塞,直到有东西要接收。因此,当涉及到Receive调用时,您的程序将“冻结”。 -
所以我需要创建线程?
-
不,请参阅
sf::SocketTCP::SetBlocking函数。