Programming Languages
C
API
Berkeley Socket API
Data Structure used to store socked details
struct sockaddr_in6 {
u_char sin6_len; // length of this structure
u_char sin6_family; // AF_INET6
u_int16m_t sin6_port; // Transport layer port #
u_int32m_t sin6_flowinfo; // IPv6 flow information
struct in6_addr sin6_addr; // IPv6 address
};
Filling the socket local address
// Declare the vars to use struct sockaddr_in6 localaddress, remoteaddress; // Fill the structures with zero's memset(&localaddress,0,sizeof(localaddress)); memset(&remoteaddress,0,sizeof(remoteaddress)); // Client socket details // Listen on any ipv6 address localaddress.sin6_addr = in6addr_any; // Address Family AF_INET6 is required localaddress.sin6_family = AF_INET6; // A client usually runs on a random port, the server has a static port localaddress.sin6_port = 0; // Server socket details // Fill remote.sin6_addr with the network address inet_pton(AF_INET6,"2001:41d0:1:f574::1111", &remote.sin6_addr); // Address Family AF_INET6 is required remote.sin6_family = AF_INET6; // Server port remote.sin6_port = htons(8000);
Creating the socket
int socket(int domain, int type, int protocol);
domain
AF_UNIX – UNIX internal protocols
AF_INET – ARPA Internet protocols
AF_ISO – ISO protocols
AF_NS – Xerox Network Systems protocols
AF_IMPLINK – IMP host at IMP link layer
Type
SOCK_STREAM – provides sequenced, reliable, two-way connection based byte streams
SOCK_DGRAM – connectionless, unreliable messages of a fixed (typically small) maximum length
SOCK_RAW – sockets provide access to internal network protocols and interfaces
SOCK_SEQPACKET – provide a sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length
SOCK_RDM – Not implemented
Returns
0 – Error
1+ – Socket descriptor
Bind the socket
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
socket – Socket descriptor
address – Socket address (address, port, family…)
address_len – Structure address size
Connect to remote socket
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
socket – Socket descriptor
address – Socket address (address, port, family…)
address_len – Structure address size
Returns
0 – OK
-1 – Error
Read and write from a socket
It works exactly like when we’re reading from a file, pipe, etc.
Read from socket
read(sockd, &buffer, 100);
Write to socket
write(sockd, &buffer, strlen(buffer));
Client code revealed
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
void newConnectionHandler(int sockd){
char buffer[100] = {'t', 'e', 's', 't', '\0'};
if(write(sockd, &buffer, strlen(buffer)) < 1)
perror("Unable to write on socket");
if(read(sockd, &buffer, 100) < 0)
perror("Unable to read from socket");
printf("Received: %s\n", buffer);
}
int main(int argc, char *argv[])
{
int sockd,newsockd,tmpint;
struct sockaddr_in6 localaddress,remoteaddress;
fd_set descriptorslist;
struct timeval timeout;
// Client address
memset(&localaddress,0,sizeof(localaddress));
localaddress.sin6_addr = in6addr_any;
localaddress.sin6_family = AF_INET6;
localaddress.sin6_port = 0;
// Server address
memset(&remoteaddress,0,sizeof(remoteaddress));
inet_pton(AF_INET6, "2001:41d0:1:f574::1111", &remoteaddress.sin6_addr);
remoteaddress.sin6_family = AF_INET6;
remoteaddress.sin6_port = htons(8000);
// Create the socket
if((sockd = socket(AF_INET6, SOCK_STREAM,0))<1){
perror("Unable to create socket");
return 1;
}
// Bind socket sockfd on localaddress
if(bind(sockd, (struct sockaddr *)&localaddress, sizeof(localaddress)) != 0){
perror("Unable to bind socket");
return 1;
}
tmpint = sizeof(remoteaddress);
if(connect(sockd,(struct sockaddr *)&remoteaddress, tmpint) == -1){
perror("Unable to connect");
return 1;
}
newConnectionHandler(sockd);
}
-
Categories
-
Articles



