linux socket通信组件,linux高级编程之socket进程通信(示例代码)

Socket套接字不仅可以用于网络通信和局域网通信还可以用于本地的进程通信。

创建套接字时使用本地协议PF_UNIX,套接字分为流失套接字,数据报套接字。

Socket本地进程通信较其他的进程间通信方式(管道,system Ⅴ,BSD)使用更加方便、效率。

本地地址结构:

Struct  sockaddr_un   //

{

Sa_family_t sun_family;

Char sun_path[108]; //套接字的文件路径

}

填充地址结构:

1、定义:struct sockaddr_un myaddr;

2、置零:bzero(&myaddr,sizeof(myaddr));

3、配置:

myadd.sun_family=AF_UNIX;

strcpy(myadd.sun_path,”mysock”);//名字可以随意命名

一、UNIX域流式套接字服务器端的创建过程:

Socket(AF_UNIX,SOCK_STREAM,0)

Bind(,本地地址,)

Listen(,)

Accept(,,)

Recv()/send()

UNIX域流式套接字客户端的创建过程:

Socket(AF_UNIX,SOCK_STREAM,0)

Bind(,本地地址,)//可选

Connect(,,)

Recv()/send()

…….

以下为创建的服务器端和客户端实现简单的进程间的通信:

服务器端:

Server.c

#include

#include

#include

#include

#include

#include

#include

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

{

int n,sockfd,length,connfd;

struct sockaddr_un  myaddr,clientaddr;

char buf[128];

// 创建套接字

sockfd=socket(PF_UNIX,SOCK_STREAM,0);

if(sockfd<0)

{

perror("socket");

return -1;

}

//置零

bzero(&myaddr,sizeof(myaddr));

//配置套接字

myaddr.sun_family=AF_UNIX;

strcpy(myaddr.sun_path,"mysocket");

//绑定套接字

if((bind(sockfd,(struct sockaddr*)&myaddr,sizeof(myaddr)))<0)

{

perror("bind");

return -1;

}

//监听套接字

if((listen(sockfd,10))<0)

{

perror("listen");

return -1;

}

length=sizeof(clientaddr);

while(1)

{

connfd=accept(sockfd,(struct sockaddr*)&clientaddr,&length);

if(connfd<0)

{

perror("accept");

return -1;

}

while((n=recv(connfd,buf,127,0))>0)

{

buf[n]=‘\0‘;

printf("receive:%s\n",buf);

send(connfd,buf,strlen(buf),0);

}

if(strncmp(buf,"quit",4)==0)

{

break ;

}

close(connfd);    //关闭套接字

}

return 0;

}

客户端:

Client.c

#include

#include

#include

#include

#include

#include

#include

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

{

int n,sockfd,length;

char buf[128];

struct sockaddr_un myaddr;

//创建套接字

sockfd=socket(AF_UNIX,SOCK_STREAM,0);

if(sockfd<0)

{

perror("socket");

return -1;

}

//置零

bzero(&myaddr,sizeof(myaddr));

//配置套接字

myaddr.sun_family=AF_UNIX;

strcpy(myaddr.sun_path,"mysocket");

//链接客户端

if (connect(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0)

{

perror("connect");

exit(-1);

}

do

{

fgets(buf,128,stdin);

length=strlen(buf)+1;

if (send(sockfd, buf, length, 0) < 0)

{

perror("send");

exit(-1);

}

memset(buf, 0, sizeof(buf));

length = recv(sockfd, buf, 128, 0);

if (length <= 0)

{

break;

}

buf[length] = ‘\0‘;

printf("receive:%s\n", buf);

}

while(strncmp(buf,"quit",4)!=0);   //当输入quit时退出客户端

close(sockfd);//关闭套接字

return 0;

}

编译执行后,效果如图所示:

20180110205836256232.png

二、UNIX域用户数据报套接字服务器端的创建过程:

UNIX域用户数据报套接字服务器的创建过程:、

Socket(AF_UNIX,SOCK_STREAM,0)

Bind(,本地地址,)//可选

Recvfrom()           ←

↓                     ↑

Sendto()          ↑

↓      →        →  ↑

UNIX域用户数据报套接字客户端的创建过程:

Socket(AF_UNIX,SOCK_STREAM,0)

Bind(,本地地址,)//可选

Recvfrom()/sendto()

……

客户端:

Server.c

#include

#include

#include

#include

#include

#include

#include

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

{

int n,sockfd;

socklen_t slength;

struct sockaddr_un  myaddr,clientaddr;

char buf[128];

//创建套接字

sockfd=socket(PF_UNIX,SOCK_DGRAM,0);

if(sockfd<0)

{

perror("socket");

return -1;

}

//置零

bzero(&myaddr,sizeof(myaddr));

//配置套接字

myaddr.sun_family=AF_UNIX;

strcpy(myaddr.sun_path,"mysocket");

//绑定套接字

if((bind(sockfd,(struct sockaddr*)&myaddr,sizeof(myaddr)))<0)

{

perror("bind");

return -1;

}

slength=sizeof(clientaddr);

while(1)

{

if((n=recvfrom(sockfd,buf,127,0,(struct sockaddr*)&clientaddr,&slength))>0)

{

buf[n]=‘\0‘;

printf("receive:%s\n",buf);

sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,sizeof(clientaddr));

}

if(strncmp(buf,"quit",4)==0)

{

break ;

}

}

close(sockfd);

return 0;

}

客户端:

Client.c

#include

#include

#include

#include

#include

#include

#include

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

{

int n,m,sockfd,length;

socklen_t slength;

char buf[128];

struct sockaddr_un temp,myaddr;

//创建套接字

sockfd=socket(AF_UNIX,SOCK_DGRAM,0);

if(sockfd<0)

{

perror("socket");

return -1;

}

//置零服务器套接字内存空间

memset(&temp, 0, sizeof(temp));

//配置套接字

temp.sun_family = AF_UNIX;

strcpy(temp.sun_path, "mysocket");

//置零客户端套接字内存空间

bzero(&myaddr,sizeof(myaddr));

myaddr.sun_family=AF_UNIX;

strcpy(myaddr.sun_path,"mysock");

//绑定

if((bind(sockfd,(struct sockaddr*)&myaddr,sizeof(myaddr)))<0)

{

perror("bind");

return -1;

}

slength=sizeof(temp);

do

{

fgets(buf,128,stdin);

buf[strlen(buf)-1]=0;

if (sendto(sockfd, buf, strlen(buf)+1, 0,(struct sockaddr*)&temp,sizeof(temp)) < 0)

{

perror("send");

exit(-1);

}

memset(buf, 0, sizeof(buf));

length = recvfrom(sockfd,buf,128,0,(struct sockaddr*)&temp,&slength);

if (length  <= 0)

{

break;

}

buf[length] = ‘\0‘;

printf("receive:%s\n", buf);

}while(strncmp(buf,"quit",4)!=0);

close(sockfd);

return 0;

}

执行后:

20180110205836265021.png

总结:

看似unix的流式套接字和用户数据报套接字的区别不大,但是在实际操作的过程中,却有着非常大的区别,在本文中,unix用户数据报套接字在客户端中再次绑定了和设置了一个套接字,这样做的目的在于如果不创建这个套接字,服务器发送给客户端时由于是UDP协议没有确定的地址,导致服务器无法找到接受的那个客户端以至于无法发送信息过去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值