struct MSGHDR and struct IOVEC

Source: Internet
Author: User
Tags sendmsg htons
the use of struct MSGHDR#include <sys/socket.h>
struct MSGHDR {
void * MSG_NAME; /* Message Protocol Address */protocol address and socket information, in the connectionless UDP, the sender to specify the address port, the receiver used to the data source, if not necessary can be set to null (in TCP or connected UDP, generally set to null)
Socklen_t Msg_namelen; /* The length of the address */
struct Iovec * MSG_IOV; /* Multiple IO buffer address */
int Msg_iovlen; /* Number of buffers */
void * Msg_control; /* The address of the secondary data */
Socklen_t Msg_controllen; /* Length of secondary data */
int msg_flags; /* Receive the message identification */
} ;

ssize_t recvmsg (int sockfd, struct MSGHDR * msg, int flags);
ssize_t sendmsg (int sockfd, struct MSGHDR * msg, int flags);
Returns the number of bytes read and write when successful, and returns 1 when the error occurs.

These 2 functions are used only for socket interfaces, not for normal I/O reads and writes, and parameter SOCKFD is a set of interfaces to read and write.
Flags are used for incoming control information, typically including the following
Msg_dontroute Send available
Msg_donwait send and recv are available
Msg_peek recv Available
Msg_waitall recv Available
Msg_oob Send available
Msg_eor Send recv available

The return information is recorded in struct MSGHDR * msg.

Msg_name is a pointer to a structural body struct SOCKADDR
Msg.msg_name = {sa_family= af_inet, Sin_port = 0, sin_addr.s_addr = 172.16.48.1};
Msg.msg_namelen = 16; length half set to 16

The send and receive processing of multiple buffers is an array of struct IOVEC, with each member's io_base pointing to the address of a different buffer. Io_len refers to the length of data in this buffer. The Msg_iovlen in struct MSGHDR refers to the number of buffer buffers, that is, the length of the Iovec array.
The Msg_control field also points to a piece of memory, Msg_controllen refers to the total size length of the memory, which is typically used to store secondary data, and auxiliary data can be used for some special processing. Msg_control usually points to a control message header, and its structure is as follows:

struct CMSGHDR {
Socklen_t Cmsg_len; /* Contains the data length of the head */
int cmsg_level; /* Specific Protocol identification */
int cmsg_type; /* The type in the agreement */
} ;

Sample 1, using SENDMSG and recvmsg in TCP

Server
......
#define MAXSIZE 100


int main (int argc, char * * Argu) {
.......
struct MSGHDR msg;//initialization struct MSGHDR
Msg.msg_name = NULL; In TCP, you can set to NULL
struct Iovec io;//initialization return data
Io.iov_base = BUF; Only one buffer was used
Io.iov_len = MAXSIZE; Define the length of the returned data
Msg.msg_iov = &io;
Msg.msg_iovlen = 1;//uses only one buffer, so the length is 1


...................
ssize_t recv_size = recvmsg (CONNFD, &msg, 0);
char * temp = msg.msg_iov[0].iov_base;//Gets the data
Temp[recv_size] = '; '//Add a terminator to the end of the data
printf ("Get message:%s", temp);
..........................
}

Client
..................
#define MAXSIZE 100
int main (int argc, char * * argv) {
.................
struct MSGHDR msg;//Initialize send message
Msg.msg_name = NULL;
struct Iovec io;
Io.iov_base = Send_buff;
Io.iov_len = sizeof (Send_buff);
Msg.msg_iov = &io;
Msg.msg_iovlen = 1;


if (argc!= 2) {
printf ("Please input port");
Exit (1);
}
............
ssize_t size = sendmsg (sockfd, &msg, 0);
Close (SOCKFD);
Exit (0);
}

Here the control information is set to 0, primarily to initialize the return information struct MSGHDR structure

Disconnected UDP Socket Interface
Server
#include "/programe/net/head.h"
#include "stdio.h"
#include "Stdlib.h"
#include "string.h"
#include "Unistd.h"
#include "Sys/wait.h"
#include "Sys/select.h"
#include "sys/poll.h"

#define MAXSIZE 100
int main (int argc, char * * argv) {
int sockfd;
struct sockaddr_in serv_socket;
struct sockaddr_in * client_socket = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
Char buf[maxsize + 1];

SOCKFD = socket (af_inet, SOCK_DGRAM, 0);
Bzero (&serv_socket, sizeof (Serv_socket));
serv_socket.sin_family = af_inet;
SERV_SOCKET.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
Serv_socket.sin_port = htons (atoi (argv[1));
Bind (SOCKFD, (struct sockaddr *) &serv_socket, sizeof (Serv_socket));

struct MSGHDR msg;
Msg.msg_name = Client_socket;
If you want to get the address and port of each other, be sure to put the initialized memory head pointer into msg
Msg.msg_namelen = sizeof (struct sockaddr_in);//length to be specified
struct Iovec io;
Io.iov_base = BUF;
Io.iov_len = MAXSIZE;
Msg.msg_iov = &io;
Msg.msg_iovlen = 1;


ssize_t len = recvmsg (sockfd, &msg, 0);
Client_socket = (struct sockaddr_in *) msg.msg_name;
Char ip[16];
Inet_ntop (Af_inet, & (client_socket->sin_addr), IP, sizeof (IP));
int port = Ntohs (Client_socket->sin_port);
char * temp = msg.msg_iov[0].iov_base;
Temp[len] = ' the ';
printf ("Get Message from%s[%d]:%s\n", IP, port, temp);
Close (SOCKFD);
}

Client
#include "/programe/net/head.h"
#include "stdio.h"
#include "Stdlib.h"
#include "string.h"
#include "Sys/select.h"

#define MAXSIZE 100
int main (int argc, char * * argv) {
int sockfd;
struct sockaddr_in serv_socket;
int MAXFDPL;
Char send[] = "Hello Yuna";
if (argc!= 2) {
printf ("Please input port");
Exit (1);
}
SOCKFD = socket (af_inet, SOCK_DGRAM, 0);
Bzero (&serv_socket, sizeof (Serv_socket));
serv_socket.sin_family = af_inet;
Serv_socket.sin_port = htons (atoi (argv[1));
Inet_pton (Af_inet, "192.168.1.235", &serv_socket.sin_addr);

struct MSGHDR msg;
Msg.msg_name = &serv_socket;
Msg.msg_namelen = sizeof (struct sockaddr_in);
struct Iovec io;
Io.iov_base = send;
Io.iov_len = sizeof (send);
Msg.msg_iov = &io;
Msg.msg_iovlen = 1;

ssize_t send_size = sendmsg (sockfd, &msg, 0);
Close (SOCKFD);
Exit (0);
}
definition and use of IOVEC structure bodyThe READV (2) and Writev (2) functions all use the concept of an I/O vector. This is defined by the included file:
#include <sys/uio.h>
The header file defines the struct IOVC, which is defined as follows:
struct Iovec {
ptr_t iov_base; /* Starting Address * *
size_t Iov_len; /* Length in bytes * *
};
struct Iovec defines a vector element. Typically, this structure is used as an array of multiple elements. For each transmitted element, the pointer member Iov_base points to a buffer that holds the data that READV receives or the data that Writev will send. Member Iov_len determines the maximum length of the received and the length of the actual write, respectively, in various cases.

int readv (int fd, const struct IOVEC *vector, int count);
int Writev (int fd, const struct IOVEC *vector, int count);
These functions require three parameters:
The file descriptor to be read or written on is FD
I/o vector (vector) for reading or writing
Number of vector elements to use (count)
The return value of these functions is the number of bytes read by READV or the number of bytes written by Writev. If an error occurs, it returns-1, and errno contains the error code. Note that other I/O functions are similar and can return an error code EINTR to indicate that he was interrupted by a signal.

/*
* WRITEV.C
*
* Short Writev (2) Demo:
*/
#include
int main (int argc,char **argv)
{
static char part2[] = "This are from Writev";
static char part3[] = "]\n";
static char part1[] = "[";
struct Iovec iov[3];
Iov[0].iov_base = Part1;
Iov[0].iov_len = strlen (part1);
Iov[1].iov_base = Part2;
Iov[1].iov_len = strlen (part2);
Iov[2].iov_base = Part3;
Iov[2].iov_len = strlen (PART3);
Writev (1,iov,3);
return 0;

}

Article reference:

Http://blog.sina.cn/dpool/blog/s/blog_c2b97b1d01016tra.html

http://blog.163.com/lichuan0502@126/blog/static/9933534820111033228285/

http://blog.csdn.net/newnewman80/article/details/8000533

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.