















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
The impact of choosing blocking or non-blocking sockets on application responsiveness and efficiency. It also covers quality of service (qos) parameters, socket options, and buffer rules for transport-layer protocols. Explanations of various socket options, their usage, and the difference between blocking and non-blocking sockets.
Typology: Study notes
1 / 23
This page cannot be seen from the preview
Don't miss anything!
11
Transport Layer - Quality Of Service (QOS) 1 The design of the communication aspects of a distributed application will have a significant impact on the quality of Service (QoS) achieved. For example:
Socket Options 1 Sockets are the endpoints of transport-layer communication. As such these need to be quite versatile. Options that can be selected for use with a particular socket include:
Socket Options 2 RECALL - setsockopt() Prototype: int setsockopt( SOCKET s , int level , int optname , const char* optval , int optlen ); If no error occurs, setsockopt returns zero. Otherwise, it returns an error code level is the level at which the option applies (usually SOL_SOCKET ) optname is the name of the option to set optval is the value to set the option to optlen is the length of the value data Example: char cOpt[2]; cOpt[0] = 1; // true cOpt[1] = 0; // null terminate the option array int iError = setsockopt(m_SendSOCKET, SOL_SOCKET, SO_BROADCAST, cOpt, sizeof(cOpt)); if(SOCKET_ERROR == iError) { MessageBox("setsockopt() Failed!","Simple Send Dialog"); }
Socket Address Structure struct sockaddr { unsigned short int sa_family; // address family char sa_data[14]; // up to 14 bytes of address }; This structure stores the socket address family (AF-INET for IP addresses) and the name that has been 'bound' to the socket. sa_family has fixed size of 2 bytes (u_short means unsigned short integer). sa_data has a variable size. A special version of the Socket Address Structure is used with IP addresses: struct sockaddr_in { short int sin_family; // Address family unsigned short int sin_port; // Port number struct in_addr sin_addr; // Internet address }; where: struct in_addr { unsigned long int s_addr; // Internet address ( 32 bits ) };
Buffering (rules for the Transport-layer protocols) The operating system only buffers messages for ports known to be in use (i.e. such that a process is likely to retrieve the message from the buffer). This leads to some important behaviour that must be considered when designing an application’s communication logic:
Blocking vs Non Blocking behaviour 2 Operations on a Non-Blocking socket will return an error if they cannot complete immediately i.e. they remain responsive. The error code is WOULD-BLOCK and is not an error in the true sense. It signals to the process that the operation could not be completed at that time. For example, a non blocking recv will take a packet from the buffer if one is already there, or it will return with the error code WOULD-BLOCK. The usual way to deal with this situation is to use a timer to wait a short time and then try again. The process can get on with other work in-between the retries. Sockets can be switched between blocking and non-blocking modes by using setsockopt at any time between the socket’s creation and its closure.
Blocking vs Non Blocking behaviour 3 Setting a socket to be Blocking or Non-Blocking A socket by default operates in ‘Blocking’ mode. It can be changed between the two modes, to suit application requirements. Class header file (.h) #define BLOCKING 0 #define NON_BLOCKING 1 SOCKET m_RecvSOCKET; Class source file (.cpp) (create socket) unsigned long lArg = NON_BLOCKING; // or BLOCKING int iError = ioctlsocket(m_RecvSOCKET,FIONBIO,&lArg); if(SOCKET_ERROR == iError) { // Error handling, e.g. use WSAGetLastError() to get more information }
Blocking vs Non Blocking behaviour 5 Communication Deadlock If two communicating processes both set their sockets to ‘blocking’ mode, a problem can arise: If the processes work in ‘lock-step’ / synchronised fashion then all is well. i.e. Step 1: A sends, B receives Step 2: B sends, A receives Step 3: A sends, B receives … However, if the situation arises, where synchronisation is lost, and both processes wait for a message from the other one, a problem arises: Solutions: multithreaded applications, or use non-blocking socket at one end recv() blocked (cannot send) Buffer (empty) Process A (^) Process B recv() blocked (cannot send) Buffer (empty)
Timers 1 Distributed applications typically have an event-driven user interface – i.e. the client process is usually activated by the user selecting activities such as initiating a request to be sent to the server. Such event-driven processes ‘sleep’ when there are no events to process (this is the classic ‘windows’ concept, but also occurs in many other technologies). A ‘Timer’ is needed if an event needs to be generated periodically and automatically, such as checking to see if a message has arrived in the buffer when using a non-blocking socket. Check buffer for received message Check buffer for received message Check buffer for received message Method active Event Send message from buffer Time Timer expired Timer expired Timer expired Send button pressed Timer period
Timers 3 Source file (.cpp) contents include: (In the ‘message map’ section) ON_WM_TIMER() // handle timer events (General code) void class_name::InitiateTimer() { // Start timer number 1, Interval 250 milliseconds (Frequency = 4Hz) m_nTimer = SetTimer( 1, 250, 0 ); } void class_name::StopTimer() { KillTimer( m_nTimer ); // Stop the timer } void class_name::OnTimer( unsigned int nIDEvent ) { // Timer event-handler // Code here runs when the timer expires, e.g. non-blocking receive) } // nIDEvent signals which timer has expired (ignore if only using one)
User Interface 1 List control 1 Example use – within the O’s and X’s game, this was used to list the other players available to have a game with. List Control Names are added to the list when a player registers with the server Names are removed from the list when a player becomes part of a game To create - Add a new resource from the toolbox. Right-click and select ‘Properties’ to change its name etc. Example code (header file) // Define the maximum length of strings that can be placed in the listbox #define MAX_ALIAS_LEN 30 // This does not have to be part of the actual class // Declare the variable in the header file (.h) for the class CListBox m_PlayerListBox; // Can use right click on resource, ‘add variable’
User Interface 1 List control 3 Example code continued - source file for the class (.cpp) // To add an entry to the listbox char sPlayerAlias[MAX_ALIAS_LEN + 1]; strcpy( sPlayerAlias , ”Champion” ); m_PlayerListBox.AddString( sPlayerAlias ); // Set default selection to the top item in the list m_PlayerListBox.SetCurSel( 0 ); // Get the index of the actual item selected int iSelection = m_PlayerListBox.GetCurSel(); // Get the actual text for the selected item char sBuffer[MAX_ALIAS_LEN + 1]; int iLen = m_PlayerListBox.GetText( iSelection , sBuffer );
User Interface 2 Slider control 1 Example use – to change the speed of a game, or to select a sound volume, difficulty level etc. To create - Add a new resource from the toolbox. Right-click and select ‘Properties’ to change its name etc. Example code (header file) // Declare the slider control CSliderCtrl m_Speed; // Can use right click on resource, ‘add variable’ Slider control