,,C语言 socketpair用法案例讲解

,,C语言 socketpair用法案例讲解

本文主要介绍C语言中socketpair用法的案例讲解。本文通过一个简单的案例来说明对这项技术的理解和使用。以下是详细内容,有需要的朋友可以参考一下。

socket()函数的声明:

#包含sys/types.h

#包含sys/socket.h

int socketpair(int d,int type,int protocol,int SV[2]);

socket()函数用于创建一对相互连接的无名套接字。

如果函数成功,则返回0,创建的套接字分别为sv[0]和SV[1];否则,返回-1,错误代码保存在errno中。

基本用法:

这一对套接字可以用于全双工通信,每个套接字都可以被读取或写入。比如你可以写sv[0],读SV[1];或者从sv[1]写,从sv[0]读;

如果你写一个套接字(比如sv[0])然后从那个套接字读会阻塞,你只能在另一个套接字(sv[1])读成功;

读写操作可以在同一个进程中,也可以在不同的进程中,比如父子进程。如果是父子进程,通常功能是分开的,一个进程读,一个进程写。因为文件描述对sv[0]和sv[1]是由进程共享的,所以读进程应该关闭写描述符,否则,写进程应该关闭读描述符。

示例:

一、读写操作位于同一进程

#包含stdio.h

#包含字符串. h

#包括unistd.h

#包含sys/types.h

#包含错误. h

#包含错误号h

#包含sys/socket.h

#包含stdlib.h

const char* str='套接字对测试';

int main(int argc,char* argv[]){

char buf[128]={ 0 };

int socket _ pair[2];

pid _ t pid

if(socketpair(AF_UNIX,SOCK_STREAM,0,socket_pair)==-1 ) {

printf('Error,socketpair create失败,errno(%d): %s\n ',errno,strerror(errno));

返回EXIT _ FAILURE

}

int size=write(socket_pair[0],str,strlen(str));

//可以成功阅读;

read(socket_pair[1],buf,size);

printf('读取结果:%s\n ',buf);

返回EXIT _ SUCCESS

}

二、读写操作位于不同进程

#包含stdio.h

#包含字符串. h

#包括unistd.h

#包含sys/types.h

#包含错误. h

#包含错误号h

#包含sys/socket.h

#包含stdlib.h

const char* str='套接字对测试';

int main(int argc,char* argv[]){

char buf[128]={ 0 };

int socket _ pair[2];

pid _ t pid

if(socketpair(AF_UNIX,SOCK_STREAM,0,socket_pair)==-1 ) {

printf('Error,socketpair create失败,errno(%d): %s\n ',errno,strerror(errno));

返回EXIT _ FAILURE

}

PID=fork();

如果(pid 0) {

printf('Error,fork failed,errno(%d): %s\n ',errno,strerror(errno));

返回EXIT _ FAILURE

} else if(pid 0) {

//关闭另一个套接字

close(socket _ pair[1]);

int size=write(socket_pair[0],str,strlen(str));

printf('写入成功,pid: %d\n ',getpid());

} else if(pid==0) {

//关闭另一个套接字

close(socket _ pair[0]);

read(socket_pair[1],buf,sizeof(buf));

printf('读取结果:%s,pid: %d\n ',buf,getpid());

}

for(;) {

睡眠(1);

}

返回EXIT _ SUCCESS

}

sendmsg, recvmsg , send函数的使用

三个函数的头文件:sendmsg,recvmsg,send:

#包含sys/types.h

#包含sys/socket.h

Sendmsg函数

定义函数

int sendmsg(int s,const strcut msghdr *msg,unsigned int flags);

函数描述:sendmsg()用于将数据从指定的套接字传输到另一个主机。

参数s:已建立连接的套接字。如果使用UDP协议,则没有连接操作。

参数msg:指要连接的数据结构内容,参数flags一般默认为0。详细描述请参考send()。

返回值:成功返回发送的字节数,错误返回-1。

Recvmsg函数

定义函数

int recvmsg(int s,struct msghdr *msg,unsigned int flags);

函数:recvmsg()用于通过指定的套接字从远程主机接收数据。

参数s是已建立连接的套接字。如果使用UDP协议,则不需要连接操作。

msg参数指向要连接的数据结构内容,

参数flags一般设置为0,详细描述请参考send()。

返回值:如果成功,则返回接收的字符数,如果失败,则返回-1。错误原因存储在errno中。

发送功能

定义:int send (int s,constvoid * msg,int len,unsigned int falgs);

函数描述:send()用于将数据从指定的套接字发送到另一台主机。

参数s是已建立连接的套接字。

msg参数指向要连接的数据内容。

参数len是数据长度。

参数flags一般设置为0,其他值定义如下:

MSG_OOB发送的数据是带外发送的

MSG_DONTROUTE取消路由表查询

MSG_DONTWAIT设置为非阻塞操作。

MSG_NOSIGNAL这个动作不愿意被SIGPIPE信号中断。

返回值:如果成功,返回实际传输的字符数;如果失败,将返回-1。错误原因存储在errno中。

结构msghdr定义如下:

结构msghdr

{

void * msg _ name//发送或接收数据的地址

socklen _ t msg _ namelen//地址长度

strcut iovec * msg _ iov//发送或接收数据

size _ t msg _ iovlen//容器数据长度

void * msg _ control//辅助数据

size _ t msg _ controllen//明细数据长度

int msg _ flags//收到的消息的标志

};

返回值:如果成功,返回实际传输的字符数;如果失败,将返回-1;错误原因将存储在errno中。

错误代码:

1.EBADF参数s是一个非法的套接字处理代码。

2.默认参数中的指针指向不可访问的内存空间。

3.ENOTSOCK参数s是一个文件描述符,而不是一个套接字。

4.EINTR被信号中断。

5.伊根。这个操作会阻塞进程,但是参数s的套接字是不可阻挡的。

6.ENOBUFS系统的缓冲内存不足。

7.ENOMEM的核心内存不足,EINVAL传递给系统调用的参数不正确。

辅助数据消息_控制结构

控制头本身由以下C结构定义:

结构cmsghdr {

socklen _ t cmsg _ len

int cmsg _ level

int cmsg _ type

/* u _ char cmsg _ data[];*/

};

其成员描述如下:

成员描述

cmsg_len附属数据的字节数,包含结构头的大小。这个值是由CMSG _伦()宏计算的。

值cmsg_level表示原始协议级别(例如,SOL_SOCKET)。

cmsg_type的值指示控制信息的类型(例如,SCM_RIGHTS)。

成员cmsg_data实际上并不存在,它用于指示实际附加附属数据的位置。

使用sendmsg传输数据程序实例

/*sendmsg.c*/

#包含stdio.h

#包含stdlib.h

#包括unistd.h

#包含错误号h

#包含字符串. h

#包含sys/types.h

#包含sys/socket.h

int main(int argc,char *argv[])

{

int ret/*返回值*/

int sock[2];/*插座对*/

struct msghdr msg

struct io vec iov[1];

char send_buf[100]='这是一个测试';

结构msghdr msgr

struct io vec iovr[1];

char recv _ buf[100];

/*创建套接字对*/

ret=socketpair(AF_LOCAL,SOCK_STREAM,0,SOCK);

if(ret==-1){

printf(' socket pair err \ n ');

返回1;

}

/* sock[1]向本地主机发送数据*/

bzero(msg,sizeof(msg));

msg.msg _ name=NULL/* void* type NULL本地地址*/

msg . msg _ name len=0;

iov[0]。iov _ base=send _ buf

iov[0]。iov _ len=sizeof(send _ buf);

msg.msg _ iov=iov//要发送或接收的数据设置为iov

msg . msg _ iov len=1;//1个元素

Printf('开始发送数据:\ n ');

Printf('发送的数据是:%s\n ',send _ buf);

ret=sendmsg(sock[1],msg,0);

if(ret==-1 ){

printf(' sendmsg err \ n ');

return-1;

}

Printf('发送成功!\ n’);

/*通过sock[0]接收发送的数据*/

bzero(msg,sizeof(msg));

msgr.msg _ name=NULL

msgr . msg _ name len=0;

iovr[0]。iov _ base=recv _ buf

iovr[0]。iov _ len=sizeof(recv _ buf);

msgr.msg _ iov=iovr

msgr . msg _ iov len=1;

ret=recvmsg(sock[0],msgr,0);

if(ret==-1 ){

printf(' recvmsg err \ n ');

return-1;

}

Printf('接收成功!\ n’);

Printf('接收的数据:%s\n ',recv _ buf);

/*关闭套接字*/

close(sock[0]);

close(sock[1]);

返回0;

}

执行结果:

Yu @ Ubuntu:~/Linux/217/pro _ pool/socket pair $ gcc-o sendmsg sendmsg . c

Yu @ Ubuntu:~/Linux/217/pro _ pool/socket pair $。/sendmsg

开始发送数据:

发送的数据是:这是一个测试。

发送成功!

已成功接收!

收到的数据是:是测试。

程序分析:Socket sock[1]向本地主机发送数据,Socket sock[0]接收发送的数据。

本文关于C语言socketpair使用案例的讲解到此为止。关于C语言socketpair用法的更多信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • 详解c语言中的字符串数组是什么,详解c语言中的字符串数组结构,详解C语言中的字符串数组
  • 表达式求值c++实现,c语言实现表达式求值
  • 看懂c语言基本语法,C语言详解,C语言的基本语法详解
  • 用c语言实现快速排序算法,排序算法设计与实现快速排序C语言,C语言实现快速排序算法实例
  • 深入解析c语言中函数指针的定义与使用方法,深入解析c语言中函数指针的定义与使用情况,深入解析C语言中函数指针的定义与使用
  • 描述E-R图,E-R图举例,关于C语言中E-R图的详解
  • 折半查找法C语言,折半查找算法(算法设计题)
  • 折半查找法C语言,c语言折半法查找数据,C语言实现折半查找法(二分法)
  • 扫雷小游戏c++代码设计,c语言扫雷游戏源代码,C语言实现扫雷小游戏详细代码
  • 怎样统计程序代码行数,C语言统计行数,C#程序员统计自己的代码行数
  • 基于c语言的贪吃蛇游戏程序设计,用c语言编写贪吃蛇游戏程序,C语言实现简单的贪吃蛇游戏
  • 图的两种遍历算法,图的遍历算法代码c语言,Python算法之图的遍历
  • 留言与评论(共有 条评论)
       
    验证码: