7

你心中最高大上最牛逼的技术到底是什么大声告诉我

 3 years ago
source link: https://studygolang.com/articles/32437
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

6Zfiamy.png!mobile

IN3AnmR.png!mobile

借用一句话,

西北玄天一片云,乌鸦落进凤凰群

满网都是英雄汉,谁是君来谁是臣

下面就是要告诉你所谓的牛逼技术到底是什么回事!!!

我们测试一下数据库,java,python,go,c/c++,php,redis,docker进行测试【测完你会发现点东西】

然后你再看图比较好,免得大家天天为了这个框架,那个框架,这个语言,哪个语言在b乎,快手,抖音,b站吵的跟少妇一样[只是吐槽一下]

^_^

  • 先测试数据库接收数据时是不是用了Linux网络 socket API

Q32Afim.png!mobile

好启动了,没有什么可说的,ELF文件启动。

Aziy6ff.png!mobile

.ibd是创建数据表时生成的文件,没啥可说的,DBA专业都知道

eMZZneU.png!mobile

我画线的地方调用了ACCEPT SOCKET API函数

BbQjAjy.png!mobile

调用了SENDTO,RECVFROM SOCKET API 函数

mysql怎么实现我们管不着,但是数据来回的传输依赖于LINUX SOCKET API,这些都是网络接口API

URvaAnf.png!mobile

u6ruUvI.png!mobile

调用了系统其它API函数库,我们看一下accept,sendto,recvfrom,setsockopt,getsockopt read,write,epoll相关函数

3YFZFn.png!mobile

YZF7JbA.png!mobile

EzINjeQ.png!mobile

FBn2amR.png!mobile

uqYvQff.png!mobile

QZF3qii.png!mobile

UNrYZnv.png!mobile

  • redis 数据库

Jr63Arj.png!mobile

启动redis

3EVBZf.png!mobile

测试

fMJbmm.png!mobile

**epoll_wait 得到就绪的文件描述符读事件返回,然后调用read,其实跟RECVFROM功能一样

它的数据是:3\r\n$3\r\nset\r\n4\r\nbfzs\r\n5\r\n10000\r\n

这一堆数据被各种大佬称为 redis的二进制通信请求协议!!!返回是+OK\r\n**

n2yemaQ.png!mobile

它们的数据来回传输大部分用read,write函数来实现

a6NNjeU.png!mobile

mu6Zr26.png!mobile

iMvERvi.png!mobile

yaqMBfU.png!mobile

  • docker

RVrUvyi.png!mobile

yqueUfI.png!mobile

dockerd服务ELF文件调用的linux api相关函数库

NRzuYfy.png!mobile

启动docker服务,跟mysql一样默认启动一堆进程和线程

e6nymqQ.png!mobile

相关命令运行【对不起,我不喜欢背东西,你要是面试我时,问我docker有哪些命令选项,对不起我回家种地放牛了】

Y7bIZvI.png!mobile

来用下测试

UVFfey3.png!mobile

运行过程

yINvme2.png!mobile

vieqaq6.png!mobile

都在调用connect,socket,getpeerame,setsockopt,getsockopt,accept,sendto等LINUX SOCKET API函数

docker调用的LINUX API 函数库

rqiyyuy.png!mobile

ZbQn6rq.png!mobile

3QVZFnA.png!mobile

QnimEnn.png!mobile

IJri6rR.png!mobile

  • go语言写个网络程序

我直接复制粘粘给你运行对不起我背不了函数,要用就直接复制粘粘就好了

7zy2eey.png!mobile

nmaeYv3.png!mobile

go ELF 文件

ABfQZrM.png!mobile

来运行那个大家认为的源码文件

IVBnmav.png!mobile

先运行哪个函数,你自己看着办哦

BjaaUrf.png!mobile

重点

Vf2meqn.png!mobile

熟悉的一批,socket 创建socket文件描述符,然后命名【把ip,端口绑定到此文件上】,然后监听,并阻塞在accept函数上

juARRb2.png!mobile

NrYRbmN.png!mobile

An2mIvQ.png!mobile

好了,go就这样子,它封装的比较骚,go elf编译器封装的牛逼,语法换了一套就称为编译型语言了。

  • python语言也写个网络程序测试下

6BNRZbV.png!mobile

py的语法就是好,随便一撸就可以了,简直是粗暴又骚,语法嘛就这样,长得跟少妇一样

来先认识一下python elf文件 毕竟好多爬虫大佬可能没有见过

IBZfuyj.png!mobile

vAvq6fz.png!mobile

.php .py .go .java里的东西只是个文本内容,你们嘛叫源码,我没有文化,只能叫ascii text ^_^

eU7Nvy7.png!mobile

启动测试

JNbmiqu.png!mobile

73UVRnf.png!mobile

有没有发现,熟悉的一批

u2IZbi3.png!mobile

v6r6b2z.png!mobile

EFbMr2I.png!mobile

好了,到这里够意思了。

这么简单的语言,你去学语法就行了,简单又粗暴谁不喜欢呢。我都喜欢。 ^_^

  • java 语言网络程序测试

看一下java elf文件,我相信java大佬肯定知道我就不费话了

vi6v2u2.png!mobile

FR7BBfQ.png!mobile

编译一下

J7nyAjA.png!mobile

我没有学过java,但是看一下报错就知道了,对不对,这么明显的提示,我phper都晓得 ^_^

Eb6FNfb.png!mobile

编译ok

NvQvQzY.png!mobile

编译好是啥文件

fMjmEbf.png!mobile

启动java程序开始测试

m2y6Jvj.png!mobile

RRvAniq.png!mobile

有没有发现,熟悉的一批

NF3y2yA.png!mobile

A3Eryqm.png!mobile

bInUzaq.png!mobile

好了,就这么多就行了,没有必要再截图了。

看接下,我们撸c[c++一样]

你们应该看出点熟悉的地方了
int main(int argc,char *argv[])
{

        if(argc<=2){

                printf("useage:%s ip_address port_number\n",basename(argv[0]));
                return 1;
        }

        const char *ip = argv[1];
        int port = atoi(argv[2]);

        int ret = 0;
        struct sockaddr_in address;
        bzero(&address,sizeof(address));
        address.sin_family = AF_INET;
        inet_pton(AF_INET,ip,&address.sin_addr);
        address.sin_port = htons(port);

        int listenfd = socket(PF_INET,SOCK_STREAM,0);
        assert(listenfd>=0);

        ret = bind(listenfd,(struct sockaddr*)&address,sizeof(address));

        assert(ret!=-1);

        ret = listen(listenfd,5);
        assert(ret!=-1);

        bzero(&address,sizeof(address));
        address.sin_family = AF_INET;
        inet_pton(AF_INET,ip,&address.sin_addr);
        address.sin_port = htons(port);

        int udpfd = socket(PF_INET,SOCK_DGRAM,0);
        assert(udpfd>=0);

        ret = bind(udpfd,(struct sockaddr*)&address,sizeof(address));
        assert(ret!=-1);

        struct epoll_event events[MAX_EVENT_NUMBER];
        int epollfd = epoll_create(5);
        assert(epollfd!=-1);

        addfd(epollfd,listenfd);
        addfd(epollfd,udpfd);

        while(1){

                int number = epoll_wait(epollfd,events,MAX_EVENT_NUMBER,-1);
                if(number<0){

                        printf("epoll failre\n");
                        break;
                }

                for(int i=0;i<number;i++){

                        int sockfd = events[i].data.fd;
                        if(sockfd ==listenfd){

                                struct sockaddr_in client_address;
                                socklen_t client_addrlength = sizeof(client_address);
                                int connfd = accept(listenfd,(struct sockaddr*)&client_address,&client_addrlength);
                                addfd(epollfd,connfd);
                        }
                        else if(sockfd == udpfd){

                                char buf[UDP_BUFFER_SIZE];
                                memset(buf,0,UDP_BUFFER_SIZE);
                                struct sockaddr_in client_address;
                                socklen_t client_addrlength = sizeof(client_address);

                                ret = recvfrom(udpfd,buf,UDP_BUFFER_SIZE-1,0,(struct sockaddr*)&client_address,&client_addrlength);
                                if(ret>0){

                                        sendto(udpfd,buf,UDP_BUFFER_SIZE-1,0,(struct sockaddr*)&client_address,client_addrlength);
                                }
                        }
                        else if(events[i].events & EPOLLIN){

                                char buf[TCP_BUFFER_SIZE];
                                while(1){

                                        memset(buf,0,TCP_BUFFER_SIZE);
                                        ret = recv(sockfd,buf,TCP_BUFFER_SIZE-1,0);
                                        if(ret<0){

                                                if((errno==EAGAIN)||(errno=EWOULDBLOCK)){

                                                        break;
                                                }
                                                close(sockfd);
                                                break;
                                        }
                                        else if(ret==0){

                                                close(sockfd);
                                        }
                                        else{

                                                send(sockfd,buf,ret,0);
                                        }
                                }
                        }else{

                                printf("something else happened\n");
                        }
                }
        }

        close(listenfd);
        return 0;
}

然后编译,编译好就这样

rmyAf2e.png!mobile

eMnUVvf.png!mobile

测试

UBNBBzZ.png!mobile

aIBBzeA.png!mobile

好了,都不用我废话了,接下来还是测试下php吧,我觉得,虽然有的朋友觉得php咋样咋样,拍黄片嘛,在打黄打非的压力之下当然没啥好名声了。不过我就是色批,就是撸php了怎么了嘛。

  • php 网络程序测试
  • vmamUba.png!mobile

看下php elf文件

iMjEF37.png!mobile

启动并测试跟踪

uaQv63a.png!mobile

好了,不用我废话,大家也知道是怎么回事了。

IZF773z.png!mobile

这些api函数怎么用呢?

man socket

BZV3ayq.png!mobile

下面是堆废话【慎看^_^】

如果你是个注重核心技术的朋友,可以关注我的资料 https://edu.51cto.com/sd/75a3d ,同时愿你成为大佬!

因为你学哪门语言都一样。如果你觉得你想又简单又能快速的进入到socket api编程那么此资料就非常适合你。

linux socket api 是所有语言,数据库等应用的核心低层技术知识,你框架掌握的再6,没有多少意义,语言掌握得再6也只是工具,你要掌握的是数据来回传输靠的TCP/IP协议,而这些协议的相关API 就是LINUX SOCKET API,做为一名码农我觉得你有必要学这套!!!没有这套SOCKET API 或是你没有掌握,那只能受制于人!天天为表面的语法,框架,语言争吵。

分布式,集群,高大上的技术都要TCP/IP支持,而它的实现就是网络编程,各语言写法不同,但是核心基础知识没有变化,正所谓天下大事必作于细天下难事必作于易,一上来撸c/c++,java如果不合适你,那么上来就撸PHP掌握了共通的知识再换语言又何妨呢?

有疑问加站长微信联系(非本文作者)

eUjI7rn.png!mobile

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK