首页 > 其他分享 >Socket 初探

Socket 初探

时间:2024-04-28 14:25:25浏览次数:16  
标签:addr int fd 初探 msg include Socket socket

什么是Socket

在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据
  socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。
  我的理解就是Socket就是该模式的一个实现:即socket是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。
  Socket()函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。

Socket基础

首先看一个基于TCP的CS案例,客户端连接到服务器后,收到服务器发来的消息并打印,为步骤清晰,去掉了一些差错判断。

Server

#include <iostream>
#include <sys/socket.h> // int     socket(int, int, int);
#include <netinet/in.h> // IPPROTO_TCP
#include <arpa/inet.h> // in_addr_t	 inet_addr(const char *);
#include <unistd.h> //write and read

int setAddr(sockaddr_in * addr,short port,const char * ip){
    memset(addr, 0, sizeof(sockaddr_in));  //每个字节都用0填充
    addr->sin_family = AF_INET;  //使用IPv4地址
    addr->sin_addr.s_addr = inet_addr(ip);  //具体的IP地址
    addr->sin_port = htons(port);  //端口,使用htons转换为网络字节序
    return 0;
}

int main() {
    // 配置地址:ip port 协议
    sockaddr_in addr{};
    setAddr(&addr,1234,"127.0.0.1");

    // 创建socket
    int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  
    // 绑定socket和addr
    if(0!=bind(fd, (struct sockaddr *) &addr, sizeof(addr))){
        std::cout << "bind failed!" << std::endl;
    }

    // 监听指定地址端口
    if(0!=listen(fd, 20)){
        std::cout << "listen failed!" << std::endl;
    }

    //接收连接请求
    sockaddr_in clientAddr{};
    socklen_t clientAddrLen = sizeof(clientAddr);
    int clientFd = accept(fd, (struct sockaddr*)&clientAddr, &clientAddrLen);

    //向客户端发送数据
    char str[] = "Welcome!";
    write(clientFd, str, sizeof(str));

    //关闭套接字
    close(clientFd);
    close(fd);

    return 0;
}

Client

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int setAddr(sockaddr_in * addr,short port,const char * ip){
    memset(addr, 0, sizeof(sockaddr_in));  //每个字节都用0填充
    addr->sin_family = AF_INET;  //使用IPv4地址
    addr->sin_addr.s_addr = inet_addr(ip);  //具体的IP地址
    addr->sin_port = htons(port);  //端口
    return 0;
}

int main() {

    // 地址
    sockaddr_in addr{};

    setAddr(&addr,1234,"127.0.0.1");

    //1创建socket
    int fd = socket(AF_INET, SOCK_STREAM, 0);
  
    //2连接到socket
    if(0!=connect(fd,(struct sockaddr*)&addr,sizeof(addr) ) ){
        std::cout<<"connect failed!"<<std::endl;
    }

    //3读取服务器传回的数据
    char buffer[40];
    read(fd, buffer, sizeof(buffer)-1);
    printf("%s\n", buffer);

    //4关闭
    close(fd);
    return 0;
}

相关结构

typedef unsigned char           __uint8_t;
typedef __uint8_t               sa_family_t;
typedef __uint16_t              in_port_t;
typedef __uint32_t      				in_addr_t; 

struct sockaddr {
	__uint8_t       sa_len;
	sa_family_t     sa_family;//__uint8_t
	char            sa_data[14];
};

struct in_addr {
	in_addr_t s_addr;//__uint32_t
};

struct sockaddr_in {
	__uint8_t       sin_len;		//1byte
	sa_family_t     sin_family;	//1byte
	in_port_t       sin_port;		//2byte
	struct  in_addr sin_addr;		//4byte
	char            sin_zero[8];//8byte
};

相关函数

socket

/*
 * @file #include <sys/socket.h>
 * @brief create an endpoint for communication 
 * @param domain
 * 	PF_LOCAL(AF_UNIX)        		Host-internal protocols, formerly called PF_UNIX,
 * 	PF_UNIX(AF_UNIX)         		Host-internal protocols, deprecated, use PF_LOCAL,
 * 	PF_INET(AF_INET)         		Internet version 4 protocols,
 * 	PF_ROUTE(AF_ROUTE)        	Internal Routing protocol,
 * 	PF_KEY(pseudo_AF_KEY)       Internal key-management function,
 * 	PF_INET6(AF_INET6)        	Internet version 6 protocols,
 * 	PF_SYSTEM(AF_SYSTEM)       	System domain,
 * 	PF_NDRV(AF_NDRV)         		Raw access to network device,
 * 	PF_VSOCK(AF_VSOCK)        	VM Sockets protocols
 *
 * @param type
 * 	SOCK_STREAM			stream socket
 *	SOCK_DGRAM			datagram socket
 *	SOCK_RAW				raw-protocol interface
 *
 * @param protocol	usrally 0
 *	IPPROTO_TCP
 *	IPPROTO_UDP
 *	... more in netinet/in.h
 *
 * @return -1 if an error occurs, otherwise the return value is a descriptor referencing the socket.
 * 
 * ERRORS
     The socket() system call fails if:
     [EACCES]           Permission to create a socket of the specified type and/or protocol is denied.
     [EAFNOSUPPORT]     The specified address family is not supported.
     [EMFILE]           The per-process descriptor table is full.
     [ENFILE]           The system file table is full.
     [ENOBUFS]          Insufficient buffer space is available.  The socket
                        cannot be created until sufficient resources are freed.
     [ENOMEM]           Insufficient memory was available to fulfill the request.
     [EPROTONOSUPPORT]  The protocol type or the specified protocol is not supported within this domain.
     [EPROTOTYPE]       The socket type is not supported by the protocol.
     If a new protocol family is defined, the socreate process is free to return any desired error code.  
     The socket() system call will pass this error code along (even if it is undefined).
 */
int socket(int domain, int type, int protocol);

bind

/*
 * @file #include <sys/socket.h>
 * @brief bind a file descriptor with sockaddr
 * @param socket 			socket file descriptor
 * @param addr				point of addr struct
 * @param socklen_t 	size of addr
 */
int     bind(int socket, const struct sockaddr * addr, socklen_t) 

listen

/*
 * @file #include <sys/socket.h>
 * @brief bind a file descriptor with sockaddr
 * @param socket 				socket file descriptor
 * @param backlog				maximum length for the queue of pending connections
 * @return value 0 if successful; otherwise the value -1
 */
int listen(int socket, int backlog);

accept

/*
 * @file #include <sys/socket.h>
 * @brief bind a file descriptor with sockaddr
 * @param socket 									socket file descriptor
 * @param restrict_address				maximum length for the queue of pending connections
 * @param restrict_address_len		maximum length for the queue of pending connections
 * @return -1 on error,a non-negative integer that is a descriptor for the accepted socket if it succeeds.
 */
int accept(int socket, struct sockaddr *restrict_address, socklen_t *restrict_address_len);

read & write

/*
 * @file #include <unistd.h>
 * @brief read or write data from fd to buffer
 */
ssize_t	 read(int fd, void * buffer, size_t buffer_size) ;
ssize_t	 write(int fd, const void * buffer, size_t buffer_size) 

close

/*
 * @file #include <unistd.h>
 * @brief close a opened fd
 */
int  close(int fd);

recv & send

上述例子中使用了read和write函数对socket进行读取和写入数据,事实上,操作socket的数据有更好的方式,即使用recv函数和send函数。

send

#include <sys/socket.h>
/*
 * @brief send is used to transmit a message to another socket.
 * @param socket	socket file descriptor
 * @param buffer	message buffer
 * @param length  message bytes
 * @param flags  usrally 0。
 		The flags parameter may include one or more of the following: 
     #define MSG_OOB        0x1  // process out-of-band data 
     #define MSG_DONTROUTE  0x4  // bypass routing, use direct interface, usually used only by diagnostic or routing
     programs.
     
 * @return:
 			Upon successful completion, the number of bytes which were sent is returned. 
 			Otherwise, -1 is returned and the global variable errno is set to indicate the error.
*/
ssize_t send(int socket, const void *buffer, size_t length, int flags);

recv

#include <sys/socket.h>
/*
 * @brief recv receive messages from a socket, and may be used to receive data on
     a socket whether or not it is connection-oriented.
     
 * @param socket	socket file descriptor
 * @param buffer	message buffer
 * @param length  message bytes
 * @param flags  usrally 0。
 		The flags parameter may include one or more of the following: 
    	MSG_OOB        process out-of-band data
      MSG_PEEK       peek at incoming message
      MSG_WAITALL    wait for full request or error
     
 * @return:
 		 Return the number of bytes received, or -1 if an error occurred.
     For TCP sockets, the return value 0 means the peer has closed its half side of the connection.
*/
ssize_t recv(int socket, void *buffer, size_t length, int flags);

除此之外,还有

ssize_t sendmsg(int socket, const struct msghdr *message, int flags);
ssize_t recvmsg(int socket, struct msghdr *message, int flags);

ssize_t sendto(int socket, const void *buffer, size_t length, int flags, 
               const struct sockaddr *dest_addr, socklen_t dest_len);
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, 
                 struct sockaddr *restrict address, socklen_t *restrict address_len);

关于read/write,recv/send,recvmsg/sendmsg,recvfrom/sendto的区别

  • read/write:通用文件描述符操作函数
  • send:发送消息,send只可用于基于连接的套接字,send 和 write唯一的不同点是标志的存在,当标志为0时,send等同于write。
  • sendto 和 sendmsg:既可用于无连接的套接字,也可用于基于连接的套接字;除了套接字设置为非阻塞模式,调用将会阻塞直到数据被发送完。
  • recv:读取消息,一般只用在面向连接的套接字。
  • recvfrom和recvmsg:可同时应用于面向连接的和无连接的套接字。

使用示例参考后文。

Example - Tcp Echo Server

基于有连接的网络通信,使用send和recv进行数据的收发

recv

char buffer[4096];
ssize_t bytes = recv(cfd, (void *)&buffer, 4096, 0);

send

char buffer[4096]{"test!"};
send(client_fd, &buffer, strlen(buffer), 0)

Server

#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int , char **) {

    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        std::cerr << "Socket creat failed!"<<std::endl;
        return -2;
    }

    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(1234);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (bind(fd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr <<"bind error."<<std::endl;
        return -3;
    }
    if (listen(fd, 20) < 0) {
        std::cerr << "listen error."<<std::endl;
        return -4;
    }

    sockaddr_in client_addr{};
    socklen_t client_addr_size = sizeof(client_addr);
    int cfd = accept(fd, (sockaddr*)&client_addr, &client_addr_size);
    if (cfd < 0) {
        std::cerr << "accept error"<<std::endl;
        return -5;
    }
    close(fd);//关闭监听的socket


    char buffer[4096];
    ssize_t bytes;
    while (true) {
        bytes = recv(cfd, (void *)&buffer, 4096, 0);
        if (bytes == 0) {
            std::cout << "client disconnected."<<std::endl;
            break;
        }
        else if (bytes < 0) {
            std::cerr << "recv error."<<std::endl;
            break;
        }
        else {
            std::cout << "[client]" << std::string(buffer, 0, bytes) << std::endl;
            if (send(cfd, &buffer, bytes, 0) < 0) {
                std::cerr << "send error, exiting...\n";
                break;
            }
        }
    }
    close(cfd);

    return 0;
}

Client

#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int , char **) {

    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        std::cerr << "Socket creat error."<<std::endl;
        return -2;
    }

    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(1234);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "connect error."<<std::endl;
        return -3;
    }

    char buf[4096];
    std::string inputTemp;
    while(true) {
        std::memset(buf, 0, 4096);
        std::cout << ">";
        std::getline(std::cin, inputTemp, '\n');
        std::strcpy(buf, inputTemp.c_str());

        if (strlen(buf)==0) {
            continue;
        }
        else if (strcmp(buf, "quit")==0) {
            break;
        }

        ssize_t bytes_send = send(fd, &buf, (size_t)strlen(buf), 0);
        if (bytes_send < 0) {
            std::cerr << "send error."<<std::endl;
            break;
        }

        ssize_t bytes_recv = recv(fd, &buf, 4096, 0);
        if (bytes_recv < 0) {
            std::cerr << "recv error."<<std::endl;
        }
        else if (bytes_recv == 0) {
            std::cout << "server closed.";
        }
        else {
            std::cout << "[server]" << std::string(buf, 0, bytes_recv) << std::endl;
        }
    }
    close(fd);
    return 0;
}

Example - Udp Echo Server

基于无连接的网络通信,使用sendto和recvfrom收发消息

sendto和recvfrom也可以支持面向连接的网络通信

recvfrom

ssize_t bytes_len = recvfrom(server_fd, buf, sizeof(buf), 0, (struct sockaddr *)&client_addr, &socklen);

sendto

ssize_t bytes_len = sendto(server_fd, buf, sizeof(buf), 0, (struct sockaddr *)&client_addr, socklen);

Server

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>

int main()
{
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(1234);

    int fd = socket(AF_INET, SOCK_DGRAM, 0);//SOCK_DGRAM=>udp
    if (fd < 0){
        return -1;
    }
    if (bind(fd, (const sockaddr *)&addr, sizeof(addr))<0){
        return -2;
    }
    char buf[1024];
    sockaddr_in client_addr{};
    socklen_t   socklen = sizeof(client_addr);

    while (true)
    {
        ssize_t bytes_len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&client_addr, &socklen);
        if (bytes_len < 0){
            std::cout<<"recv failed"<<std::endl;
            break;
        }
        else{
            std::cout<<"[client]"<<buf<<std::endl;
        }

        bytes_len = sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&client_addr, socklen);
        if (bytes_len < 0){
            std::cout<<"send failed"<<std::endl;
            break;
        }
    }
    close(fd);
    return 0;
}

Client

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>

int main()
{
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(1234);

    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0){
        return -1;
    }

    ssize_t bytes_len ;
    char buf[1024] = "hello world!";
    bytes_len = sendto(fd, buf, strlen(buf), 0, (sockaddr*)&addr, sizeof(addr));
    if(bytes_len < 0){
        std::cout<<"send failed"<<std::endl;
        return -2;
    }
    bytes_len = recvfrom(fd, buf, strlen(buf), 0,nullptr, nullptr);
    if(bytes_len < 0){
        std::cout<<"recv failed"<<std::endl;
        return -3;
    }
    else{
        std::cout<<"[server]"<<buf<<std::endl;
    }
    close(fd);
    return 0;
}

Example - Sendmsg and Recvmsg

基于无连接的网络通信,使用sendto和recvfrom收发消息

sendto和recvfrom也可以支持面向连接的网络通信

首先回顾一下recvmsg和sendmsg的函数原型

struct iovec {
	void *   iov_base;      /* [XSI] Base address of I/O memory region */
	size_t   iov_len;       /* [XSI] Size of region iov_base points to */
};

struct msghdr {
	void            *msg_name;      /* [XSI] optional address */
	socklen_t       msg_namelen;    /* [XSI] size of address */
	struct          iovec *msg_iov; /* [XSI] scatter/gather array */
	int             msg_iovlen;     /* [XSI] # elements in msg_iov */
	void            *msg_control;   /* [XSI] ancillary data, see below */
	socklen_t       msg_controllen; /* [XSI] ancillary data buffer len */
	int             msg_flags;      /* [XSI] flags on received message */
};

ssize_t sendmsg(int socket, const struct msghdr *message, int flags);
ssize_t recvmsg(int socket, struct msghdr *message, int flags);

Basic Usage

详细参考:https://blog.csdn.net/weixin_45309916/article/details/107905942

char buf[1024];
sockaddr_in client_addr{};

struct iovec msg_iov[1];
msg_iov[0].iov_base = buf;
msg_iov[0].iov_len = sizeof(buf);

struct msghdr msg{};
msg.msg_name = &client_addr;
msg.msg_namelen = sizeof(client_addr);
msg.msg_iov = msg_iov;
msg.msg_iovlen = 1;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_flags = 0;

ssize_t bytes_len;

bytes_len = sendmsg(fd, &msg, 0);
bytes_len = recvmsg(fd, &msg, 0);

Server

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
int main()
{
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(1234);

    int fd = socket(AF_INET, SOCK_DGRAM, 0);//SOCK_DGRAM=>udp
    if (fd < 0){
        return -1;
    }
    if (bind(fd, (const sockaddr *)&addr, sizeof(addr))<0){
        return -2;
    }
    char buf[1024];
    sockaddr_in client_addr{};

    iovec msg_iov[1];
    msg_iov[0].iov_base = buf;
    msg_iov[0].iov_len = sizeof(buf);

    msghdr msg{};
    msg.msg_name = &client_addr;
    msg.msg_namelen = sizeof(client_addr);
    msg.msg_iov = msg_iov;
    msg.msg_iovlen = 1;
    msg.msg_control = nullptr;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;

    while (true)
    {
        ssize_t bytes_len = recvmsg(fd,&msg,0);
        if(bytes_len < 0){
            std::cout<<"recv failed"<<std::endl;
            break;
        }
        else{
            std::cout<<"[client]"<<buf<<std::endl;
        }

        //change msg
        memset(buf,0,sizeof(buf));
        strcpy(buf,"Hi,Im server!");

        bytes_len = sendmsg(fd, &msg, 0);
        if (bytes_len < 0){
            std::cout<<"send failed"<<std::endl;
            break;
        }
    }
    close(fd);
    return 0;
}

Client

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>

int main()
{
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(1234);

    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0){
        return -1;
    }

    ssize_t bytes_len ;
    char buf[1024] = "hello world!";

    iovec msg_iov{};
    msg_iov.iov_base = buf;
    msg_iov.iov_len = sizeof(buf);

    msghdr msg{};
    msg.msg_name = &addr;
    msg.msg_namelen = sizeof(addr);
    msg.msg_iov = &msg_iov;
    msg.msg_iovlen = 1;
    msg.msg_control = nullptr;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;

    bytes_len = sendmsg(fd, &msg, 0);
    if(bytes_len < 0){
        std::cout<<"send failed"<<std::endl;
        return -2;
    }

    bytes_len = recvmsg(fd,&msg,0);
    if(bytes_len < 0){
        std::cout<<"recv failed"<<std::endl;
        return -3;
    }
    else{
        std::cout<<"[server]"<<buf<<std::endl;
    }
    close(fd);
    return 0;
}

标签:addr,int,fd,初探,msg,include,Socket,socket
From: https://www.cnblogs.com/pengpengda/p/18163647

相关文章

  • 【网络通信】初探网络层次结构(OSI七层网络模型)
    ​        随着信息技术的飞速发展,网络通信已经成为现代社会不可或缺的一部分。网络通信的实现离不开网络协议栈的支持,而网络协议栈则是由多个层次组成的。这些层次各自承担着不同的任务,共同构成了网络通信的基石。本文将对网络通信中的各类层进行详细介绍,包括它们的定......
  • C# Socket 文件发送传输
    客户端向服务器发送文件:服务器:usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceServer{classPr......
  • Socket.D v2.4.12 发布(新增 python 实现)
    Socket.D协议?Socket.D是一个网络应用协议。在微服务、移动应用、物联网等场景,可替代http、websocket等。协议详情参考《官网介绍》。支持:tcp,udp,ws,kcp传输。目前:java,kotlin,javascript,node.js,python语言环境可用。go,rust,c/c++,.net正在开发中。forJava更新......
  • python——socket通信
    TCP协议是一种面向连接的协议,它在网络中提供可靠的、有序的、基于字节流的数据传输。它通过建立连接、数据的确认和重传机制等,确保数据的可靠性和顺序性。在TCP通信中,客户端和服务器之间的数据传输是双向的,双方可以相互发送和接收数据实现TCP服务器以下是一个示例,展示了如何使用......
  • fiber使用websocket--多进程版本
    多进程数据是隔离的,也就是说处理不好,不同的用户登录,其实不在一个进程,没办法直接通信解决办法:定义一个全局变量,所有进程公用,要加锁如果是单进程版本其实就跟gin框架那些一样了多线程+channel不存在数据隔离的问题main.gopackagemainimport( "flag" "fmt" "log" "sync"......
  • 如何基于Django中的WebSockets和异步视图来实现实时通信功能
    本文分享自华为云社区《结合Django中的WebSockets和异步视图实现实时通信功能的完整指南》,作者:柠檬味拥抱。在现代Web应用程序中,实时通信已经成为了必不可少的功能之一。无论是在线聊天、实时数据更新还是实时通知,都需要通过实时通信技术来实现。Django作为一个强大的Web框架,提......
  • ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib
    ERROR2002(HY000):Can'tconnecttolocalMySQLserverthroughsocket'/var/lib/mysql/mysql.sock'(2)=====================================================步骤:以下可用。(1)关闭mysql:servicemysqldstop(2)查看mysql.sock的位置(base)[root@VM-0-2-ce......
  • vuex结合websocket使用
    1、创建一个store文件夹,并在其中创建store.js文件,结合vuex:importVuefrom'vue'importVuexfrom'vuex'importcommonfrom"../common/common.js";Vue.use(Vuex)conststore=newVuex.Store({state:{/***是否需要强制登录*/......
  • websocket 压测
    压测背景:项目上线需要知道有多少个用户和导购能同时在线,并且正常使用场景分析:先进行用户端连接服务器,然后导购端在链接服务器,然后开始拉取视频列表,最后接听视频脚本设计:设置三个线程组线程组一,负责用户端链接socket,并且发送请求视频通话请求线程组二,负责导购端链接so......
  • 【安卓逆向】从逆向登录协议开始到frida rpc的初探
    本来是闲着无聊逆向一下喜马拉雅的登录协议日常抓包,分析数据包,有一个password字段想分析一下这个password这个字段,jadx搜索一下啊 经过frida多次的hook定位,发现这个方法便是加密过程,点进去可以hook一下这个方法查看一下functionhook(){letLoginRequest=Java.......