The address data structure of the socket has different forms depending on the system and the network environment. In order for the different format addresses to be passed into the socket function, the address structure must be forced to be converted to:
struct sockaddr{
sa_family_t sa_family;/* address family*/
char sa_data[];/* Variable-length address*/
...
};
The socket implementation is free to add additional members and to define the size of the Sa_data member. For example, in Linux, the structure is defined as follows
struct sockaddr{
sa_family_t sa_family; /* Address family*/
char sa_data[14];/* variable-length address*/
};
Where sa_family_t represents the communication domain of the socket. There are four main values:
Domain |
Describe |
Af_inet |
IPV4 Internet domain |
Af_inet6 |
IPV6 Internet domain |
Af_unix |
UNIX domain |
Af_unspec |
Not specified |
The functions for creating sockets are as follows
#include <sys/socket.h>
int socket (int domain, int type, int protocol);/* return file (socket) descriptor successfully, error return-1
Where domain refers to the communication field, type refers to the type of socket, the following four types are mainly
Type |
Describe |
Sock_dgram |
Fixed-length, non-connected unreliable message delivery |
Sock_ram |
Datagram Interface for IP protocol |
Sock_seqpacket |
Fixed-length, orderly, reliable connection-oriented message delivery |
Sock_stream |
Sequential, reliable, bidirectional connection-oriented byte stream |
The parameter protocol is typically zero, which means that the default protocol is selected by the given domain and socket type. When multiple protocols are supported for the same domain and socket type, you can use the protocol parameter to select a specific protocol.
An example of a multi-process communication using UNIX domain sockets (only on-premises) (the code is not easy to observe in two parts, the latter socket_unix.c to be part of it)
/* domain_socket.h @Author: Duanjigang @2006-4-11 @Desp: Declaratin of methods used for unix-domain-socket communication */#ifndef _h_ #define _h_ #include <stdio.h> #include <unistd.h> #include <sys/un.h> #include <sys/
socket.h> #define MSG_SIZE int init_send_socket (struct sockaddr_un * Addr,char * path) {int sockfd,len;
Sockfd=socket (af_unix,sock_dgram,0);
if (sockfd<0) {exit (1);
} bzero (addr,sizeof (struct sockaddr_un));
addr->sun_family=af_unix;
strcpy (Addr->sun_path,path);
return SOCKFD;
} int Init_recv_socket (char * path) {int sockfd,len;
struct Sockaddr_un addr;
Sockfd=socket (af_unix,sock_dgram,0);
if (sockfd<0) {return-1;
} bzero (&addr,sizeof (struct sockaddr_un));
addr.sun_family = Af_unix;
strcpy (Addr.sun_path, path);
unlink (path); Len= strlen (Addr.sun_path) + sizeof (addr.sun_family);
if (Bind (SOCKFD, (struct sockaddr *) &addr,len) <0) {return-1;
} return SOCKFD;
} int Receive_from_socket (int sockfd, char msg[]) {int n;
memset (msg, 0, msg_size);
N=recvfrom (SOCKFD, MSG, msg_size, 0, NULL, NULL);
if (n<=0) {return-1;
} msg[n]=0;
return n;
} int Send_to_socket (int sockfd, char msg[], const struct Sockaddr_un * addr) {int len;
Len = strlen (Addr->sun_path) +sizeof (addr->sun_family);
SendTo (SOCKFD, MSG, strlen (msg), 0, (struct sockaddr*) addr,len);
return 1; } #endif
/* MAIN.C @Author: duanjigang @ 2006-4-11 @Desp: Processes communicate with UNIX domain socket */#include "Domain_soc
Ket.h "#define PATH"/home/useless "/* process communicates through the domain-Example: parent-child process, one send, one receive */int main (void) {int pid;
/* The child process is used to send the message */if ((PID = fork ()) = = 0) {int fd, counter = 0;
Char Send_buffer[msg_size];
struct Sockaddr_un addr;
if (fd = Init_send_socket (&addr, PATH)) > 0) while (1) {memset (send_buffer, 0, msg_size); /* Prevent counter out of bounds, so make a reset judgment */sprintf (Send_buffer, "message for%d Times", counter++ >= 10000? 1
: Counter);
Send_to_socket (FD, Send_buffer, &addr);
printf ("Sender:%s\n", Send_buffer);
Sleep (1);
The}/* parent process is used to receive the message */else {int fd;
Char Recv_buffer[msg_size];
if (fd = Init_recv_socket (PATH)) > 0) while (1) {memset (recv_buffer, 0, msg_size); if (Receive_from_socket (FD, Recv_buffer)) {printf ("Receiver:%s\n", Recv_buffer);
}
}
}
}
Examples of running results:
Sender:message for 1 times
sender:message for 2 times
receiver:message for 2 times
sender:message for 3 ti Mes
receiver:message for 3 times
sender:message for 4 times
receiver:message for 4 times
Sender:messag E for 5 times
receiver:message for 5 times
Socket_unix.c
Using UNIX domain sockets communication #include <stdio.h> #include <unistd.h> #include <sys/un.h> #include <sys/socket.h&
Gt
#define MSG_MAX_SIZE 1024x768 #define PATH "a.socket"//Socket file int main () {int len;
int socket_fd;
struct Sockaddr_un addr;
Bzero (&addr, sizeof (struct sockaddr_un));
addr.sun_family = Af_unix;
strcpy (Addr.sun_path, path);
Len = strlen (Addr.sun_path) +sizeof (addr.sun_family);
if (!fork ())//child process internal code {int counter = 0;
Char Send_buffer[msg_max_size];
init send Socket SOCKET_FD = socket (Af_unix, SOCK_DGRAM, 0);
if (socket_fd<0) {printf ("Client socket error!");
return 0;
} while (1)//loop sends data message {memset (send_buffer, 0, msg_max_size);
sprintf (Send_buffer, "message for%d Times", counter++); The data information is sent to the addr specified socket file, so that the process can communicate sendto (SOCKET_FD, Send_buffer, STrlen (Send_buffer), 0, (struct sockaddr*) &addr, Len);
printf ("sender:%s\n", Send_buffer);
Sleep (1);
}} else {char recv_buffer[msg_max_size];
init recv Socket SOCKET_FD = socket (Af_unix, SOCK_DGRAM, 0);
if (socket_fd<0) {printf ("Server Socket error!");
return 0; } unlink (PATH);//prevents the socket file to be created already exists if (bind (SOCKET_FD, (struct sockaddr *) &addr, Len) <0)//Only
The socket Path {printf ("bind error") will not be created on the hard disk after bind.
return 0;
} while (1)//loop receives data {memset (recv_buffer, 0, msg_max_size); The receive from socket reads data from the specified socket, where the socket is already bound to the file of the specified path Recvfrom (socket_fd, Recv_buffer, msg_max_size, 0,
NULL, NULL);
printf ("Receive Message:%s\n", Recv_buffer);
}} return 0;
}