UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
FAQ
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
UnigineScript
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
CIGI Client Plugin
Rendering-Related Classes

Unigine::Socket Class

Header: #include <UnigineStreams.h>
Inherits: Stream

This class provides basic functionality for network interaction using stream sockets.

Usage Example#

In this example we create UDP sockets: server and five clients.

  • The server sends broadcast packets containing the ID of the receiving client.
  • Each client processes only the messages, that were addressed to it.
  • In the world's update() method the server sends messages addressed to clients 2 and 5.

In the AppWorldLogic.h header file we describe our client and server and declare server and array of clients.

Source code (C++)
// AppWorldLogic.h

/* ... */

// UDP port to be used
const int UDP_PORT = 8889;

// UDP receive buffer size 
const int RECV_SIZE = 7;

// UDP send buffer size
const int SEND_SIZE = 7;

/* ... */

/// Class representing the Server Socket
class ServerSocket
{
public:
	/// Server constructor
	ServerSocket()
	{
		// creating a UDP socket
		socket = Unigine::Socket::create(Unigine::Socket::SOCKET_DGRAM);
		
		// opening a socket on the specified port with a specified broadcast address
		socket->open("127.255.255.255", UDP_PORT);

		// setting the size of the sending buffer
		socket->send(SEND_SIZE);
		
		// setting the socket as a broadcasting one
		socket->broadcast();

		// setting the socket as a non-blocking one
		socket->nonblock();
	}
	
	/// Server destructor
	~ServerSocket()
	{
		// closing the socket
		socket->close();
		
		// destroying the socket
		socket.destroy();
	}
	
	/// method sending a message to a certain client
	void send_message(int client_num, const char *message)
	{
		// preparing a message to be received by a client with a given client_id
		Unigine::BlobPtr blob = Unigine::Blob::create();
		blob->clear();
		blob->writeShort(client_num);
		blob->write(message, strlen(message));
		int size = blob->getSize();

		// sending the message
		socket->write(blob->getData(), blob->getSize());
		blob.clear();
	}

private:
	// socket pointer
	Unigine::SocketPtr socket;
};

/// Class representing the Client Socket
class ClientSocket {

public:

	/// Client constructor
	ClientSocket()
	{
		// creating a UDP socket
		socket = Unigine::Socket::create(Unigine::Socket::SOCKET_DGRAM);

		// opening a socket on the specified port 

		socket->open(UDP_PORT);

		// setting the size of the receiving buffer
		socket->recv(RECV_SIZE);

		// binding the socket to an address figured out from the host used for socket initialization
		socket->bind();

		// setting the socket as a non-blocking one
		socket->nonblock();
	}
	
	/// Client destructor
	~ClientSocket()
	{
		// closing the socket
		socket->close();

		// destroying the socket
		socket.destroy();
	}
	
	void setID(int num)
	{
		// setting client's ID
		id = num;
	}
	
	/// method checking for received packes from the server
	int update()
	{
		// preparing a blob to read the message into
		Unigine::BlobPtr temp_blob = Unigine::Blob::create();
		temp_blob->clear();

		// reading data from the socket
		socket->readStream(temp_blob->getStream(), RECV_SIZE);

		if (temp_blob->getSize() > 0){

			// setting current position to start
			temp_blob->seekSet(0);

			// getting client's ID
			int num_client = temp_blob->readShort();

			// checking if the received message is addressed to this particular client and processing it
			if (num_client == id){
				Unigine::Log::message("\nClient[%d] - OPERATION_CODE: %s", id, temp_blob->readLine().get());
			}
		}
		return 1;
	}
private:
	// socket pointer
	Unigine::SocketPtr socket;

	// client ID
	int id = 0;
};



class AppWorldLogic : public Unigine::WorldLogic {
	
public:

/* ... */

private:

	// declaring client and server sockets
	ServerSocket server_socket;
	ClientSocket clients[5];
};

/* ... */

In the AppWorldLogic.cpp implementation file we do the following:

  • In the AppWorldLogic::init() method we initialize our clients.
  • In the AppWorldLogic::update() we check which keys were pressed and send messages to corresponding clients:
    • Client 2 - on ENTER key
    • Client 5 - on WASD keys
    Here we also call update() method for all clients to process server's messages.

Here are the AppWorldLogic::init() and AppWorldLogic::update() methods:

Source code (C++)
// AppWorldLogic.cpp

using namespace Unigine;

/* ... */

int AppWorldLogic::init() 
{
	//initializing clients IDs
	for (int i = 0; i < 5; i++)
		clients[i].setID(i+1);

	return 1;
}

int AppWorldLogic::update() 
{
	// getting player's controls
	ControlsPtr controls = Game::get()->getPlayer()->getControls();

	// sending messages on keys pressed to clients 2 and 5
	if (controls->clearState(Controls::STATE_USE))
		server_socket.send_message(2, "SWT");
	else if (controls->clearState(Controls::STATE_FORWARD))
		server_socket.send_message(5, "F");
	else if (controls->clearState(Controls::STATE_BACKWARD))
		server_socket.send_message(5, "B");
	else if (controls->clearState(Controls::STATE_MOVE_LEFT))
		server_socket.send_message(5, "L");
	else if (controls->clearState(Controls::STATE_MOVE_RIGHT))
		server_socket.send_message(5, "R");

	// updating clients
	for (int i = 0; i < 5; i++)
		clients[i].update();

	return 1;
}
/* ... */

See Also#

A set of UnigineScript API samples located in the <UnigineSDK>/data/samples/systems/ folder:

  • socket_00
  • socket_01
  • socket_02
  • socket_03
  • socket_04

Socket Class

Members


static SocketPtr create ( int type )

Creates a socket and opens it on a given port. When the socket receives data, packets from all network interfaces will be received. When the socket sends data, the default IP address will be used.

Arguments

  • int type - Port, on which the socket will be opened.

static SocketPtr create ( int type, int port )

Creates a socket for TCP or UDP connections and opens it on a given port. When the socket receives data, packets from all network interfaces will be received. When the socket sends data, the default IP address will be used.

Arguments

  • int type - Socket for TCP (SOCKET_STREAM variable) or UDP (SOCKET_DGRAM) connections.
  • int port - Port, on which the socket will be opened.

static SocketPtr create ( int type, const char * host, int port )

Creates a socket for TCP or UDP connections and opens it on a given host and a given port. The host specifies the address, from and to which data will be sent.

Arguments

  • int type - Socket for TCP (SOCKET_STREAM variable) or UDP (SOCKET_DGRAM) connections.
  • const char * host - Host, on which the socket will be opened.
  • int port - Port, on which the socket will be opened.

Ptr<Socket> cast( const Ptr<Stream> & stream )

Arguments

  • const Ptr<Stream> & stream

int getFD( )

Returns the socket file descriptor.

Return value

Socket file descriptor.

const char * getHost( )

Returns the host name on which the socket is opened.

Return value

Host name.

int getPort( )

Returns the port number on which the socket is opened.

Return value

Port number.

int accept( const Ptr<Socket> & socket )

Accepts a connection on the socket.

Arguments

  • const Ptr<Socket> & socket - Socket that is bound to an address and listens to connections.

Return value

1 if the connection is accepted; otherwise, 0.

int bind( )

Binds the socket to an address figured out from the host used for socket initialization.

Return value

1 if the address is bound; otherwise, 0.

int block( )

Sets up a blocking socket.

Return value

1 if the socket is opened; otherwise, 0.

int broadcast( )

Sets up a broadcast socket. To create a broadcast socket, you need to create it with a broadcast host address first and then use this function.

Return value

1 if the socket is set up successfully ; otherwise, 0 is returned.

int close( )

Closes the socket.

int connect( )

Initiates a connection on the socket.

Return value

1 if the connection is initialized; otherwise, 0.

int listen( int num )

Makes the socket listen to connections.

Arguments

  • int num - Maximum number of pending connections.

Return value

1 if the socket has started listening; otherwise, 0.

int listenMulticastGroup( )

Joins the socket to a multicast group. Available for UDP sockets only.
Notice
The socket class doesn't allow creating a multicast server.
Source code (C++)
const int PORT = 8888;
SocketPtr socket = Socket::create(Socket::SOCKET_DGRAM, PORT);
socket->listenMulticastGroup();

Return value

1 if the sockect has been joined successfully; otherwise, 0.

int nodelay( )

Enables Nagle's algorithm.

Return value

1 if the algorithm has been enabled successfully; otherwise, 0.

int nonblock( )

Makes the socket a non-blocking one.

Return value

1 if the has become non-blocking; otherwise, 0.

int open( int port )

Opens the socket on a given port. When the socket receives data, packets from all network interfaces will be received. When the socket sends data, the default IP address will be used.

Arguments

  • int port - Port number, on which the socket will be opened.

Return value

1 if the socket is opened successfully; otherwise, 0.

int open( const char * host, int port )

Opens the socket on a given port. When the socket receives data, packets from all network interfaces will be received. When the socket sends data, the default IP address will be used.

Arguments

  • const char * host - Host name, on which the socket will be opened.
  • int port - Port number, on which the socket will be opened.

Return value

1 if the socket is opened successfully; otherwise, 0.

int recv( int size )

Resizes an internal receiving buffer for a socket.

Arguments

  • int size - Receive buffer size in bytes.

Return value

1 if the buffer is resized successfully; otherwise, 0.

int send( int size )

Resizes an internal sending buffer for a socket.

Arguments

  • int size - Send buffer size in bytes.

Return value

1 if the buffer is resized successfully; otherwise, 0.

int isReadyToRead( int timeout_usec = 0 )

Returns a value indicating whether the socked is ready for reading data, waiting if necessary, to perform synchronous I/O.

Arguments

  • int timeout_usec - The maximum time for to wait for the socket's response, in microseconds. By default, the timeout is 0

Return value

1 if the socket is ready for reading data; otherwise, 0.
Last update: 2019-02-14