socketpair原理_socket负载均衡

socketpair原理_socket负载均衡描述先看下传统的CS模型,如下:总是一方发起请求,等待另一方回应。当一次传输完成之后,client端发起新的请求之后,server端才作出回应。那如何才能做到双向通信? 一种解决办法就是client端即使client,又是server,server端即使client也是server,如下:但是上述方面比较复杂,这时候就引入要分析的socketpair了。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

描述

先看下传统的CS模型,如下:
socketpair原理_socket负载均衡

总是一方发起请求,等待另一方回应。当一次传输完成之后,client端发起新的请求之后,server端才作出回应。 那如何才能做到双向通信?  一种解决办法就是client端即使client,又是server,server端即使client也是server,如下:
socketpair原理_socket负载均衡

但是上述方面比较复杂,这时候就引入要分析的socketpair了。

socketpair用于创建一对相互连接的unnamed socket。而pipe系统调用使用创建的pipe也是相互连接的unnamed pipe(无名管道)。而pipe和socketpair创建的描述符之间的区别就是:  pipe创建的描述符一端只能用于读,一端用于写,而socketpair创建的描述符任意一端既可以读也可以写。

原理

socketpair原理_socket负载均衡

使用socketpiar创建的是一对相互连接的socket,任意一段既可以做发送,也可以做接受端。所有每个socket描述符中应该有两个buf。一个为发送buf,一个为接受buf。如上图所示。

示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>

#define SOCKET_BUFFER_SIZE      (32768U)


void *thread_function(void *arg)
{
    int len = 0;
    int fd  = *((int*)(arg));
    char buf[500];
    int cnt = 0;

    /*主线程*/
    while(1)
    {        
        /*向main thread线程发送数据*/
        len = sprintf(buf, "Hi, main process, cnt = %d", cnt++);
        write(fd, buf, len);
    
        /*读数据*/
        len = read(fd, buf, 500);
        buf[len]='
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#define SOCKET_BUFFER_SIZE      (32768U)
void *thread_function(void *arg)
{
int len = 0;
int fd  = *((int*)(arg));
char buf[500];
int cnt = 0;
/*主线程*/
while(1)
{        
/*向main thread线程发送数据*/
len = sprintf(buf, "Hi, main process, cnt = %d", cnt++);
write(fd, buf, len);
/*读数据*/
len = read(fd, buf, 500);
buf[len]='\0';
printf("%s\n",buf);
sleep(5);    
} 
return NULL;
}
int main()
{
int ret;
int sockets[2];
int bufferSize = SOCKET_BUFFER_SIZE;
pthread_t thread;
ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);
if(ret == -1)
{
printf("socketpair create error!\n");
return -1;
}
/*设置socket描述符的选项*/
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
/*创建线程1*/
pthread_create(&thread, NULL, thread_function, (void*)(&sockets[1]));
int len = 0;
int fd  = sockets[0];
char buf[500];
int cnt = 0;
/*主线程*/
while(1)
{
/*读数据*/
len = read(fd, buf, 500);
buf[len]='\0';
printf("%s\n",buf);
/*项thread线程发送数据*/
len = sprintf(buf, "Hi, thread process, cnt = %d", cnt++);
write(fd, buf, len);
}
return 0;
}
'; printf("%s\n",buf); sleep(5); } return NULL; } int main() { int ret; int sockets[2]; int bufferSize = SOCKET_BUFFER_SIZE; pthread_t thread; ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets); if(ret == -1) { printf("socketpair create error!\n"); return -1; } /*设置socket描述符的选项*/ setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); /*创建线程1*/ pthread_create(&thread, NULL, thread_function, (void*)(&sockets[1])); int len = 0; int fd = sockets[0]; char buf[500]; int cnt = 0; /*主线程*/ while(1) { /*读数据*/ len = read(fd, buf, 500); buf[len]='
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#define SOCKET_BUFFER_SIZE      (32768U)
void *thread_function(void *arg)
{
int len = 0;
int fd  = *((int*)(arg));
char buf[500];
int cnt = 0;
/*主线程*/
while(1)
{        
/*向main thread线程发送数据*/
len = sprintf(buf, "Hi, main process, cnt = %d", cnt++);
write(fd, buf, len);
/*读数据*/
len = read(fd, buf, 500);
buf[len]='\0';
printf("%s\n",buf);
sleep(5);    
} 
return NULL;
}
int main()
{
int ret;
int sockets[2];
int bufferSize = SOCKET_BUFFER_SIZE;
pthread_t thread;
ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);
if(ret == -1)
{
printf("socketpair create error!\n");
return -1;
}
/*设置socket描述符的选项*/
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
/*创建线程1*/
pthread_create(&thread, NULL, thread_function, (void*)(&sockets[1]));
int len = 0;
int fd  = sockets[0];
char buf[500];
int cnt = 0;
/*主线程*/
while(1)
{
/*读数据*/
len = read(fd, buf, 500);
buf[len]='\0';
printf("%s\n",buf);
/*项thread线程发送数据*/
len = sprintf(buf, "Hi, thread process, cnt = %d", cnt++);
write(fd, buf, len);
}
return 0;
}
'; printf("%s\n",buf); /*项thread线程发送数据*/ len = sprintf(buf, "Hi, thread process, cnt = %d", cnt++); write(fd, buf, len); } return 0; }

测试结果:

1.  编译代码
gcc socketpair.c -o socketpair -lpthread

2. 运行,查看结果

test$ ./socketpair 
Hi, main process, cnt = 0
Hi, thread process, cnt = 0
Hi, main process, cnt = 1
Hi, thread process, cnt = 1
Hi, main process, cnt = 2
Hi, thread process, cnt = 2
注意:  socketpair创建的只适用于父子进程或者线程间通信,不能用于两个进程之间通信。如果要实现两个进程之间的双向通信,则需要将socketpair创建的一个描述符fd发送给另一个进程,这相当于两个两个不同的进程访问同一个文件。



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/181941.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • DOS分区表(Boot Sector引导扇区)[通俗易懂]

    DOS分区表(Boot Sector引导扇区)[通俗易懂]>>DOS分区体系的硬盘也叫MBR硬盘,0号扇区是主引导记录MBR,DOS分区体系的硬盘用分区表记录每个分区的类型起始位置和分区的大小。其中,分区表就在0号扇区内,所以0号扇区如果损坏,那么这个硬盘就不能正确识别分区。>>DOS分区的使用范围:windows系统,Linux系统以及基于IA32平台FreeDBS和OpenDBS等操作系统都使用DOS分区体系。&g…

    2022年10月23日
  • 关于UNPIVOT 操作符

    关于UNPIVOT 操作符

    2021年11月25日
  • k8s 资源管理_pod容器间调用命令

    k8s 资源管理_pod容器间调用命令k8s管理器介绍yaml资源管理器介绍管理器介绍在Kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理Kubernetes。Kubernetes的本质就是一个集群系统,用户可以在集群中部署各种服务。所谓的部署服务,其实就是在Kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。Kubernetes的最小管理单元是Pod而不是容器,所以只能将容器放在Pod中,而Kubernetes一般也不会直接管理Pod,而是通过Pod控制器来管理Pod的。Pod提供服务之后

  • 泰勒展开式「建议收藏」

    泰勒展开式「建议收藏」数学中,泰勒公式是一个用函数在某点的信息描述其附近取值的公式。如果函数足够平滑的话,在已知函数在某一点的各阶导数值的情况之下,泰勒公式可以用这些导数值做系数构建一个多项式来近似函数在这一点的邻域中的值

  • PCL点云处理算法汇总(C++长期更新版)

    PCL点云处理算法汇总(C++长期更新版)PCL学习目录

  • emWin实战教程V2.0_powershell实战指南

    emWin实战教程V2.0_powershell实战指南转 http://www.chuxue123.com/forum.php?mod=viewthread&tid=5363&extra=page%3D1   http://www.chuxue123.com/forum.php?mod=viewthread&tid=1504下面是自己的学习笔记1.emWIN与ucGUI关系,而大家所熟悉的ucGUI,其实就是emWin的一个版本

    2022年10月10日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号