Multiplayer Game Programming Berkeley Socket API Chapter 3.ppt
MoissFreitas13
18 views
29 slides
Aug 25, 2024
Slide 1 of 29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
About This Presentation
Multiplayer Game Programming
Size: 132.88 KB
Language: en
Added: Aug 25, 2024
Slides: 29 pages
Slide Content
Multiplayer Game Programming
Chapter 3
Berkeley Socket API
Chapter 3
Objectives
Socket Creation and Initialization
–How to create and bind a socket
–Platform differences
Datagram Transmission
–How to use sockets foår UDP
Stream Transmission
–How to use sockets for TCP
Blocking and Non blocking IO
–How to use sockets in realtime
Sockets
Berkeley Socket API
Originally from BSD UNIX 4.2
Ported in some way to almost every language and
operating system
Operating System Differences
POSIX: Linux, MacOSX, PlayStation, BSD
–<sys/socket.h>
–Socket is a file descriptor ( int )
Windows: Xbox
–WinSock2
–<Winsock2.h>
•Define WIN32_LEAN_AND_MEAN before
including <Windows.h>
–Socket is a SOCKET
Windows requires explicit startup and shutdown of
WinSock2
Windows Housekeeping
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData );
int WSACleanup();
Creating A Socket
SOCKET socket(
int af,
int type,
int protocol );
Returns new socket if successful
-1 if unsuccessful
–INVALID_SOCKET
Address Family
???INSERT TABLE 3.1 PLEASE
Socket Type
How will data be passed
–Tied to protocol
???INSERT TABLE 3.2 PLEASE
Protocol
???INSERT TABLE 3.3 PLEASE
When return value of -1 indicates error
–retrieve true error code in platform dependent
manner
–Do it quickly- another error in same thread will
change vlaue
Windows
int WSAGetLastError();
POSIX
int errno ;
Error Reporting
Binding Socket To Address
Registers address for use by socket
Actual type of sockaddr can change based on
protocol family, etc.
–From a time before classes and inheritance
–Different types must be cast to sockaddr
int bind(
SOCKET sock,
const sockaddr *address,
int address_len );
IN_ADDR IPv4 Address
Specify IP Address as a 32-bit number, two 16-bit numbers or four
8-bit numbers ( most common )
INADDR_ANY allows binding to all local interfaces on the host
struct in_addr {
union {
struct {
uint8_t s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
uint16_t s_w1,s_w2;
} S_un_w;
uint32_t S_addr;
} S_un;
};
Byte Order
Network Byte Order is Big Endian
Your platform is probably Little Endian
Use conversion functions when manually filling in or
reading address structures
uint16_t htons( uint16_t hostshort );
uint16_t ntohs( uint16_t netshort);
uint32_t htonl( uint32_t hostlong );
uint32_t ntohl( uint32_t netlong);
Creating Address From String
hostname: dns name or ip address
servname: port number or service name
hints: can specify address family, etc
res: results. Must be deallocated with freeaddrinfo
int getaddrinfo(
const char *hostname,
const char *servname,
const addrinfo *hints,
addrinfo **res);
Datagram Transmission
Returns number of bytes sent or -1 for error
to: destination host address
–Same format as when creating socket
Most common way to send UDP Packets
int sendto(
SOCKET sock,
const char *buf, int len,
int flags,
const sockaddr *to, int tolen );
Datagram Reception
Returns number of bytes received or -1 for error
from: output param assigned address of sending host
–Do not fill with an address before invoking
–Does not select incoming datagram based on address
•ONLY USED AS OUTPUT PARAM
Most common way to receive UDP Packets
int recvfrom(
SOCKET sock,
char *buf, int len,
int flags,
sockaddr *from, int *fromlen );
Listening for Stream Connections
backlog: number of connections that can be pending
acceptance
Returns 0 for no error
Server calls to prepare for incoming TCP handshake
int listen(
SOCKET sock,
int backlog );
Initiating Stream Connection
Sockadder: target host’s address
–Same format as when creating socket
Client calls to initiate TCP handshake
int connect(
SOCKET sock,
const sockaddr *addr,
int addrlen );
Stream Connections
Server calls to complete TCP handshake
Returns a new socket representing stream
–Encapsulates reliability buffers, flow and congestion control
values, and other state
–Use only new socket for sending and receiving
addr: output param assigned address of initiating host
SOCKET accept(
SOCKET sock,
sockaddr* addr,
int* addrlen );
Stream Transmission
Returns number of bytes sent or -1 for error
No address necessary
–Address stored in socket by connection
Copies data into send buffer for transmission
–Sent when socket decides– Nagle Algorithm!
Most common way to send TCP data
int send(
SOCKET sock,
const char *buf,
int len,
int flags );
Stream Reception
Returns number of bytes received or -1 for error
Most common way to receive TCP Packets
No param to store sender address
–data can only come from connected socket on
remote host
int recv (
SOCKET sock,
char *buf,
int len,
int flags );
Blocking
Some actions halt thread or block waiting for
completion
–Sending: when no room in send buffers
–Receiving: when no incoming data available
–Connecting: until handshake complete
–Accepting: until handshake complete
Problem for real-time simulation like game
Problem when when communicating with multiple
remote hosts sending data
Working Around Blocking
Multithreading
–Use separate thread for each connection
Non-blocking I/O
–Enable non-blocking mode and poll for updates
Select
–Block on all relevant sockets at once
Multithreading
Does not scale well for large numbers of clients
???INSERT FIGURE 3.1 PLEASE
Non-Blocking I/O
Non-Blocking sockets return control immediately
when asked to do operations that would block
–Return value is -1, but error code is indicative
•Windows: WSAEWOULDBLOCK
•POSIX: EAGAIN
–Can try again next frame to
•Send
•Receive
•Accept
•Connect
Windows
POSIX
Enabling Non-Blocking I/O
int ioctlsocket(
SOCKET sock,
long cmd,
u_long *argp );
int fcntl(int sock, int cmd, ...);
Blocking with Select
Returns number of ready sockets or negative error.
Sets are modified by function
Initialize sets to contain all relevant sockets
At return, sets contain sockets that can perform
operations without blocking
int select(
int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
const timeval *timeout );
Select Socket Set
FD_ZERO(fd_set* set )
–Initializes set
FD_SET( SOCKET s, fd_set* set )
–Add socket to set
FD_ISSET( SOCKET s, fd_set* set )
–Tests if a socket is set
FD_CLR( SOCKET s, fd_set* set )
–Removes socket from set