Appearance
TCP/IP
TCP/IP Socket Functions.
a socket interface as per the Open Group Base Specifications
Server Example
The following shows, how to create a socket, bind it to a specific address and port, accept connections, send and receive data.
It uses the socket related functions to demonstrate their use when implementing a server
c
#include "socket.h"
#include <stdio.h>
#include <string.h>
int main() {
const char *addr = "<IPv4 address>"; // Replace with an IPv4 address
in_port_t port = <port>; // Replace with a port number
// Create a socket
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) {
perror("Failed to create socket");
return -1;
}
// Bind the socket to a specific address
struct sockaddr_in name;
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.s_addr = inet_addr(addr);
if (bind(s, (struct sockaddr *)&name, sizeof(name)) < 0) {
perror("Failed to bind socket");
return -1;
}
// Start listening on the socket
if (listen(s, 1) < 0) {
perror("Failed to listen on socket");
return -1;
}
// Accept a connection
struct sockaddr_storage their_addr;
socklen_t size = sizeof(their_addr);
int new_s = accept(s, (struct sockaddr *)&their_addr, &size);
if (new_s < 0) {
perror("Failed to accept connection");
return -1;
}
// Send a message to the client
const char *message = "Welcome! This is a test server.\n";
if (send(new_s, message, strlen(message), 0) < 0) {
perror("Failed to send message");
return -1;
}
// Read a message from the client and print it
char buffer[1024];
int bytes_received = recv(new_s, buffer, sizeof(buffer) - 1, 0);
if (bytes_received < 0) {
perror("Failed to receive a message");
return -1;
}
buffer[bytes_received] = '\0';
printf("Received: %s\n", buffer);
return 0;
}
Client Example
This example demonstrates the usage of socket(), connect(), send(), recv(), and close() functions to create a TCP client
The example creates the following steps:
- Create a socket using the socket function
- Connect to the server using the connect() function
- Send a message to the server using the send() function
- Receive a response from the server using the recv() function
- Close the socket
cpp
#include "socket.h"
#include <string.h>
#include <stdio.h>
void write_and_read_from_server() {
// Create the socket
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
perror("socket()");
return;
}
// Define server information
struct sockaddr_in server_info;
server_info.sin_family = AF_INET;
server_info.sin_port = htons(8000); // Change to your server's port
server_info.sin_addr.s_addr = inet_addr("<your_server_ip_address>"); // Change to your server's IP
// Connect to the server
if (connect(sock, (struct sockaddr*)&server_info, sizeof(server_info)) < 0) {
perror("connect()");
return;
}
// Send a message to the server
const char* message = "Hello, Server!";
if (send(sock, message, strlen(message), 0) < 0) {
perror("send()");
return;
}
// Receive a response from the server
char buffer[1024];
int bytes_received = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (bytes_received < 0) {
perror("recv()");
return;
}
buffer[bytes_received] = '\0'; // Null-terminate the received data
// Print the server's response
printf("Received: %s\n", buffer);
// Shutdown the socket
shutdown(sock, SHUT_RDWR);
}
DNS Lookup Example
This example demonstrates the use of getaddrinfo and gethostbyname for DNS Resolution
cpp
#include <netdb.h>
#include <string.h> // For strcpy
void dnsResolveExample() {
// Using getaddrinfo
struct addrinfo hints;
struct addrinfo *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // Allow IPv4
hints.ai_socktype = SOCK_STREAM; // TCP socket
int status = getaddrinfo("your.domain.com", NULL, &hints, &res);
if (status != 0) {
printf("getaddrinfo error: %s\n", gai_strerror(status));
return;
}
freeaddrinfo(res); // Free the linked list
// Using gethostbyname
struct hostent *he = gethostbyname("your.domain.com");
if (he == NULL) {
printf("gethostbyname error: %s\n", hstrerror(h_errno));
return;
}
char ip[INET_ADDRSTRLEN];
inet_ntop(he->h_addrtype, he->h_addr, ip, sizeof(ip));
printf("IP:%s\n", ip);
}
Types
Name | |
---|---|
struct | hostent |
struct | addrinfo |
struct | in_addr The in_addr struct represents an IP address. |
struct | sockaddr_in IPv4 socket address structure. |
struct | sockaddr The sockaddr struct represents a generic socket address structure. |
struct | sockaddr_storage A generic structure to store socket address information. |
Functions Overview
Name | |
---|---|
struct hostent * | gethostbyname(const char * name) |
int | gethostbyname_r(const char * name, struct hostent * ret, char * buf, size_t buflen, struct hostent ** result, int * h_errnop) |
void | freeaddrinfo(struct addrinfo * ai) |
int | getaddrinfo(const char * nodename, const char * servname, const struct addrinfo * hints, struct addrinfo ** res) |
int | socket(int domain, int type, int protocol) Creates a new socket and returns its descriptor. |
int | connect(int s, const struct sockaddr * name, socklen_t namelen) Connects a socket to a remote address. |
int | bind(int s, const struct sockaddr * name, socklen_t namelen) Binds a socket to a specific address and port. |
int | listen(int s, int backlog) Set a socket into listening mode. |
int | accept(int s, struct sockaddr * addr, socklen_t * addrlen) Accept a connection on a socket. |
int | recv(int s, void * buf, size_t len, int flags) Receive data from a socket. |
int | select(int maxfdp1, fd_set * readset, fd_set * writeset, fd_set * exceptset, struct timeval * timeout) Select function. |
int | send(int s, const void * data, size_t size, int flags) Sends data on a socket. |
int | shutdown(int s, int how) Shutdown a socket connection. |
ssize_t | sendto(int s, const void * data, size_t size, int flags, const struct sockaddr * to, socklen_t tolen) Sends data over a socket to a specified destination. |
ssize_t | recvfrom(int s, void * mem, size_t len, int flags, struct sockaddr * from, socklen_t * fromlen) Receive data from a socket. |
int | fcntl(int s, int cmd, ... ) Controls file descriptor behavior. |
int | inet_pton(int af, const char * src, void * dst) Converts a string representation of an IP address to a binary format. |
const char * | inet_ntop(int af, const void * src, char * dst, socklen_t size) Converts a network address from binary to presentation format. |
int | setsockopt(int socket, int level, int option_name, const void * option_value, socklen_t option_len) Sets a socket option. |
int | getsockopt(int s, int level, int optname, void * optval, socklen_t * optlen) Retrieves options for the specified socket. |
int | getsockname(int s, struct sockaddr * name, socklen_t * namelen) Retrieves the local address of a socket. |
Function Details
function gethostbyname
cpp
struct hostent * gethostbyname(
const char * name
)
Parameters:
- name the hostname to resolve
Return: entry containing one address of family AF_INET for the host with name name
Returns an entry containing IP addresses for a hostname. Due to internal limitations, only one address is returned.
function gethostbyname_r
cpp
int gethostbyname_r(
const char * name,
struct hostent * ret,
char * buf,
size_t buflen,
struct hostent ** result,
int * h_errnop
)
Parameters:
- name the hostname to resolve
- ret pre-allocated struct where to store the result
- buf pre-allocated buffer where to store additional data
- buflen the size of buf
- result pointer to a hostent pointer that is set to ret on success and set to zero on error
- h_errnop pointer to an int where to store errors (instead of modifying the global h_errno)
Return: 0 on success, non-zero on error, additional error information is stored in *h_errnop instead of h_errno to be thread-safe
Thread-safe variant of gethostbyname: instead of using a static buffer, this function takes buffer and errno pointers as arguments and uses these for the result.
function freeaddrinfo
cpp
void freeaddrinfo(
struct addrinfo * ai
)
Parameters:
- ai struct addrinfo to free
Frees one or more addrinfo structures returned by getaddrinfo(), along with any additional storage associated with those structures. If the ai_next field of the structure is not null, the entire list of structures is freed.
function getaddrinfo
cpp
int getaddrinfo(
const char * nodename,
const char * servname,
const struct addrinfo * hints,
struct addrinfo ** res
)
Parameters:
- nodename descriptive name or address string of the host (may be NULL -> local address)
- servname port number as string of NULL
- hints structure containing input values that set socktype and protocol
- res pointer to a pointer where to store the result (set to NULL on failure)
Return: 0 on success, non-zero on failure
Translates the name of a service location (for example, a host name) and/or a service name and returns a set of socket addresses and associated information to be used in creating a socket with which to address the specified service. Memory for the result is allocated internally and must be freed by calling freeaddrinfo()!
Due to internal limitations, only the first address of a host is returned. Also, service names are not supported (only port numbers)!
function socket
cpp
int socket(
int domain,
int type,
int protocol
)
Creates a new socket and returns its descriptor.
Parameters:
- domain The domain of the socket (e.g. PF_INET for IPv4).
- type The type of the socket (e.g. SOCK_STREAM for TCP, SOCK_DGRAM for UDP).
- protocol The protocol to be used by the socket (e.g. IPPROTO_UDP).
See: errno
Return: The socket descriptor if successful, otherwise -1.
Note: This function does not provide support for SOCK_SEQPACKET or SOCK_RAW socket types.
This function creates a new socket using the specified domain, type, and protocol. The socket descriptor is returned if the socket creation is successful, otherwise -1 is returned.
function connect
cpp
int connect(
int s,
const struct sockaddr * name,
socklen_t namelen
)
Connects a socket to a remote address.
Parameters:
- s The socket file descriptor.
- name A pointer to the sockaddr structure containing the address to connect to.
- namelen The length of the sockaddr structure.
Return: Returns 0 on success and -1 on error, setting errno.
This function establishes a connection between the socket referred to by the file descriptor s and the address specified by the structure pointed to by name.
function bind
cpp
int bind(
int s,
const struct sockaddr * name,
socklen_t namelen
)
Binds a socket to a specific address and port.
Parameters:
- s The socket descriptor.
- name Pointer to a struct sockaddr containing the local address and port information.
- namelen The length of the address structure pointed to by name.
Return: 0 on success, or -1 on error.
This function assigns a local address and port to a socket. The binding is used to determine the local interface and port to send and receive data through the socket.
function listen
cpp
int listen(
int s,
int backlog
)
Set a socket into listening mode.
Parameters:
- s The socket to set to listening mode.
- backlog The maximum number of pending connections that can be queued up.
Return: 0 on success, non-zero on failure.
Note: The number of connections that can be queued up is limited by the backlog parameter, which must not exceed the value of TCP_LISTEN_BACKLOG.
This function sets a socket into listening mode. The socket must not have been used for another connection previously.
function accept
cpp
int accept(
int s,
struct sockaddr * addr,
socklen_t * addrlen
)
Accept a connection on a socket.
Parameters:
- s The socket descriptor
- addr Pointer to a sockaddr structure that will be filled with the source address and port of the incoming connection. Set to NULL if not needed.
- addrlen Pointer to an integer variable that specifies the size of the sockaddr structure. Upon return, it will be updated with the actual size of the sockaddr structure. Set to NULL if not needed.
Return: On success, the new socket descriptor is returned. On error, -1 is returned and errno is set appropriately.
Note:
- The new socket is independent of the listening socket, and can be used to communicate with the incoming client.
- The newly created socket must be closed after use, using the close() function.
- This function is blocking, and will wait until a new connection arrives.
- If addr and addrlen are not NULL, the source address and port of the incoming connection will be filled in the sockaddr structure. The sa_family field of the sockaddr structure will be set to the address family of the incoming connection. If addr is NULL, the source address and port information will not be returned.
- This function is thread-safe.
This function is used to accept a connection on a listening socket. It waits until a new connection arrives, and then creates a new socket for that connection.
function recv
cpp
int recv(
int s,
void * buf,
size_t len,
int flags
)
Receive data from a socket.
Parameters:
- s Socket descriptor.
- buf Pointer to the buffer to store the received data.
- len Maximum length of the buffer.
- flags Receive flags.
Return: On success, returns the number of bytes received. On failure, returns -1.
Note: This function is responsible for receiving data from a socket. The received data is stored in the provided buffer, up to the maximum length specified. The actual number of bytes received may be less than the maximum length, which can be checked using the return value. The flags parameter can be used to modify the behavior of the receive operation. The function accepts different flag options to control receive operations, such as OOB (Out of Band) and PEEK.
This function is used to receive data from a socket.
function select
cpp
int select(
int maxfdp1,
fd_set * readset,
fd_set * writeset,
fd_set * exceptset,
struct timeval * timeout
)
Select function.
Parameters:
- maxfdp1 The highest file descriptor value to be checked plus one.
- readset Pointer to the set of file descriptors to be checked for readability.
- writeset Pointer to the set of file descriptors to be checked for writability.
- exceptset Pointer to the set of file descriptors to be checked for exceptional conditions.
- timeout Pointer to a struct timeval specifying the maximum time to wait for an event to occur. If NULL, select will block until an event occurs.
Return: The total number of file descriptors ready and contained in the sets (i.e., the sum of the file descriptors in readset, writeset, and exceptset) if the return value is positive, or -1 on error. On error, the errno variable is set appropriately to indicate the cause of the error.
Note: The select function modifies all three descriptor sets passed as parameters.
The select function allows monitoring multiple file descriptors for readability, writability, or exceptional conditions. It is useful for multiplexing I/O operations and handling asynchronous events.
function send
cpp
int send(
int s,
const void * data,
size_t size,
int flags
)
Sends data on a socket.
Parameters:
- s Socket descriptor of the socket to send data on.
- data A pointer to the buffer containing the data to be sent.
- size The length of the data in bytes.
- flags Specifies the type of message transmission.
Return: Returns the number of bytes sent on success, or -1 on failure.
This function is used to send data on a socket.
function shutdown
cpp
int shutdown(
int s,
int how
)
Shutdown a socket connection.
Parameters:
s The socket descriptor to shutdown.
how Specifies the type of shutdown. It can have one of the following values:
SHUT_RD: Disables further receive operations.
SHUT_WR: Disables further send operations.
SHUT_RDWR: Disables further send and receive operations.
Return: 0 if successful, or -1 if an error occurred. The specific error code can be obtained by calling errno which evaluates to *cw_errno.
Note: The function shutdown
can only be used with TCP sockets. If any other socket type is used, the function will return an error with errno set to EOPNOTSUPP.
This function closes one end of a full-duplex connection identified by the socket descriptor s
. It allows either sending, receiving, or both to be shutdown. The how
parameter determines which operation(s) to shutdown.
function sendto
cpp
ssize_t sendto(
int s,
const void * data,
size_t size,
int flags,
const struct sockaddr * to,
socklen_t tolen
)
Sends data over a socket to a specified destination.
Parameters:
- s The socket descriptor.
- data A pointer to the data that should be sent.
- size The size of the data in bytes.
- flags Flags to control the behavior of the function.
- to A pointer to a
sockaddr
structure that contains the destination address. - tolen The size of the destination address structure.
Return: The number of bytes sent on success, or -1 on failure.
This function sends the specified data over the socket with the given descriptor to the specified destination address.
function recvfrom
cpp
ssize_t recvfrom(
int s,
void * mem,
size_t len,
int flags,
struct sockaddr * from,
socklen_t * fromlen
)
Receive data from a socket.
Parameters:
- s The socket descriptor.
- mem A pointer to the buffer where the received data will be stored.
- len The maximum number of bytes to receive.
- flags Specifies the type of message reception.
- from A pointer to an address structure where the source address of the data will be stored.
- fromlen Length of the address structure.
Return: On success, the number of bytes received is returned. On failure, -1 is returned. The errno variable is set to indicate the error.
The recvfrom function is used to receive data over a socket. It attempts to receive up to len bytes of data into the memory pointed to by mem.
function fcntl
cpp
int fcntl(
int s,
int cmd,
...
)
Controls file descriptor behavior.
Parameters:
- s The file descriptor.
- cmd The command to perform.
Return: The result of the operation, or -1 in case of failure.
Note: The behavior of this function is platform-dependent.
The fcntl function performs various control operations on file descriptors.
function inet_pton
cpp
int inet_pton(
int af,
const char * src,
void * dst
)
Converts a string representation of an IP address to a binary format.
Parameters:
- af The address family of the IP address (AF_INET or AF_INET6).
- src A pointer to the string containing the IP address in ASCII format.
- dst A pointer to the buffer where the binary format of the IP address will be stored.
Return: 0 if the conversion is successful, or -1 if an error occurs.
Note: The dst buffer must be large enough to hold the binary format of the IP address. The size of the buffer depends on the address family. For IPv4 addresses, the dst must be at least the size of ip4_addr_t. For IPv6 addresses, the dst must be at least the size of ip6_addr_t.
This function converts a string representation of an IP address from the specified address family (AF_INET or AF_INET6) to its binary format.
This function supports both IPv4 and IPv6 addresses. For IPv4 addresses (AF_INET), it calls the function ip4addr_aton to convert the string to a binary format. For IPv6 addresses (AF_INET6), it first converts the string to a temporary ip6_addr_t variable using ip6addr_aton, and then memcpy's the address to the destination buffer if the conversion is successful. If an unsupported address family is specified, it sets the errno to EAFNOSUPPORT and returns -1.
function inet_ntop
cpp
const char * inet_ntop(
int af,
const void * src,
char * dst,
socklen_t size
)
Converts a network address from binary to presentation format.
Parameters:
- af The address family (AF_INET or AF_INET6).
- src Pointer to binary network address.
- dst Pointer to buffer to store the resulting address string.
- size The size of the
dst
buffer.
Return: Pointer to the resulting address string on success, or NULL on failure.
This function converts the network address given in the src
buffer from binary format to a string in presentation format. The resulting address string is stored in the dst
buffer.
The af
parameter specifies the desired address family. It can be AF_INET for IPv4 or AF_INET6 for IPv6 addresses. The src
parameter is a pointer to the network address in binary format. The dst
parameter is a pointer to the buffer where the resulting address string will be stored. The size
parameter specifies the size of the buffer pointed to by dst
.
The function returns a pointer to the resulting address string if successful. However, if the size of the buffer pointed to by dst
is smaller than the resulting address string, the function sets the errno variable to ENOSPC and returns NULL.
The function supports both IPv4 and IPv6 addresses. For IPv4 addresses use (af = AF_INET) to convert the address to a string format. For IPv6 addresses use (af = AF_INET6) to convert the address to a string format.
If the desired address family is not supported (af != AF_INET or af != AF_INET6), the function sets the errno variable to EAFNOSUPPORT.
function setsockopt
cpp
int setsockopt(
int socket,
int level,
int option_name,
const void * option_value,
socklen_t option_len
)
Sets a socket option.
Parameters:
- socket The socket descriptor.
- level The level at which the option is defined (e.g. SOL_SOCKET).
- option_name The option to set.
- option_value A pointer to the option value.
- option_len The length of the option value.
Return: 0 on success, -1 on failure.
Note: This function is an implementation of the lwIP setsockopt function. It is used to set socket options such as the debug level, buffer size, etc. The level and option_name parameters determine the specific option to set, and the option_value parameter points to the new value for that option. The option_len parameter specifies the length of the option value.
This function sets the value of a socket option for a given socket.
function getsockopt
cpp
int getsockopt(
int s,
int level,
int optname,
void * optval,
socklen_t * optlen
)
Retrieves options for the specified socket.
Parameters:
- s The socket for which to get the options.
- level The level at which the option is defined.
- optname The name of the option to get.
- optval A pointer to the buffer to receive the option value.
- optlen A pointer to the size of the buffer, and on return the size of the option value.
Return: 0 on success, -1 on failure.
Par: Related Definitions
- #socklen_t: A typedef for the size of socket-related objects.
This function is used to get socket options at the specified level for the given socket.
function getsockname
cpp
int getsockname(
int s,
struct sockaddr * name,
socklen_t * namelen
)
Retrieves the local address of a socket.
Parameters:
- s The socket descriptor.
- name A pointer to a sockaddr structure that will hold the local address information.
- namelen A pointer to the length of the sockaddr structure. On input, it should contain the size of the buffer pointed to by name. On output, it will be set to the actual size of the local address returned.
See:
- getaddrname
- struct sockaddr
- struct sockaddr::sa_len
- struct sockaddr::sa_family
- struct sockaddr::sa_data
- socklen_t
Return: On success, zero is returned. On error, -1 is returned and errno is set appropriately.
This function retrieves the local address associated with a socket. The local address is returned in the form of a sockaddr structure.