当前位置: 首页 > news >正文

杭州网站优化wordpress本地访问慢

杭州网站优化,wordpress本地访问慢,缅甸网站后缀,保定软件开发网站制作目录 一、通信概念 二、进程间通信机制 1、管道 1.1 匿名管道#xff08;Anonymous Pipe#xff09; 1.2 命名管道#xff08;Named Pipe#xff09; 2、信号量 2.1 概念 2.2 API详解 2.3 使用示例 3、消息队列 3.1 概念 3.2 API函数 3.3 应用代码 4、共享内…目录 一、通信概念 二、进程间通信机制 1、管道 1.1 匿名管道Anonymous Pipe 1.2 命名管道Named Pipe 2、信号量 2.1 概念 2.2 API详解 2.3 使用示例 3、消息队列 3.1 概念 3.2 API函数 3.3 应用代码 4、共享内存 4.1 概念 4.2 API 4.3 示例代码 5、套接字 5.1 概念 5.2 API 5.3 示例代码 一、通信概念 进程间通信Inter-Process CommunicationIPC是指在操作系统中不同进程之间进行数据和信息交换的机制。这种通信允许不同的程序或进程在同一系统上进行协作共享数据和资源。常见的IPC方式包括管道、套接字、信号量、共享内存和消息队列等。这些机制使得多个进程能够相互通信和协调工作从而实现更复杂的任务。 二、进程间通信机制 1、管道 1.1 匿名管道Anonymous Pipe ①概念 匿名管道用于在具有亲缘关系例如父子进程的进程之间传递数据。 匿名管道是单向的只能用于父进程向子进程传递数据或者子进程向父进程传递数据不支持双向通信。         在创建匿名管道时使用 pipe() 系统调用来创建管道不需要指定名称。匿名管道的生命周期限于创建它们的进程及其子进程。         用于传递数据量较小的场景例如父子进程之间传递简单的命令或数据。 ②API int pipe(int pipefd[2]); 功能 创建一个匿名管道。 参数 pipefd 是包含两个整数的数组用于存储管道的文件描述符。 返回值 成功时返回0失败时返回-1。 ③示例代码 #include stdio.h #include unistd.hint main() {int pipefd[2];char buffer[20];pipe(pipefd); // 创建匿名管道pid_t child_pid fork();if (child_pid -1) {perror(fork);return 1;} else if (child_pid 0) { // 子进程close(pipefd[1]); // 关闭写入端read(pipefd[0], buffer, sizeof(buffer));printf(Child received: %s\n, buffer);close(pipefd[0]); // 关闭读取端} else { // 父进程close(pipefd[0]); // 关闭读取端write(pipefd[1], Hello from parent, 17);close(pipefd[1]); // 关闭写入端}return 0; } 1.2 命名管道Named Pipe ①概念      命名管道是一种允许不同进程之间通过一个具有唯一名称的文件进行通信的机制。      命名管道是在文件系统中创建的可以用于不同进程之间的通信甚至跨越不同的计算机。      命名管道是双向的可以在两个方向上传递数据。      创建命名管道需要使用 mkfifo 命令或者调用 mkfifo() 系统调用指定一个路径和名称。      用于传递较大数据量或者需要持久化的通信场景例如不同进程之间的实时数据传输。 ②API int mkfifo(const char *pathname, mode_t mode); 功能创建一个命名管道。 参数pathname 是管道的路径和名称mode 是管道的权限模式。 返回值成功时返回0失败时返回-1。 ③示例代码 写进程要先运行确保管道创建成功 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include fcntl.h #include sys/types.h #include sys/stat.hint main() {const char *fifoPath my_fifo;// 创建命名管道mkfifo(fifoPath, 0666);int fd open(fifoPath, O_WRONLY); // 打开管道以写入数据char message[] Hello from named pipe!;write(fd, message, strlen(message) 1);close(fd); // 关闭文件描述符return 0; } 读进程 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include fcntl.h #include sys/types.h #include sys/stat.hint main() {const char *fifoPath my_fifo;int fd open(fifoPath, O_RDONLY); // 打开管道以读取数据char buffer[100];ssize_t bytesRead read(fd, buffer, sizeof(buffer));if (bytesRead 0) {buffer[bytesRead] \0;printf(Received message: %s\n, buffer);}close(fd); // 关闭文件描述符return 0; } 2、信号量 2.1 概念 信号量是一种用于实现进程间同步和互斥的机制。它是一种同步原语用于协调多个进程对共享资源的访问以避免竞态条件Race Condition和数据冲突。信号量主要用于解决多个进程并发执行时可能出现的问题。 ①进程间通信信号量具有以下特点 同步 信号量用于确保多个进程按照特定的顺序执行。通过等待和释放信号量进程可以控制其执行的时间点从而协调操作的顺序。 互斥 信号量用于实现互斥确保在任何时刻只有一个进程能够访问共享资源。通过使用信号量进程可以避免多个进程同时修改相同的资源而引发冲突。 ②进程间通信信号量的操作通常包括以下两种 PWait操作 当一个进程想要使用共享资源时它尝试执行 P 操作。如果信号量的计数值大于零它会将计数值减少并获得访问权限。如果计数值为零该进程将被阻塞直到计数值大于零。 VSignal操作 当进程使用完共享资源时它执行 V 操作来释放信号量。这会将信号量的计数值增加并唤醒等待的进程。 ③信号量在进程间通信中有许多应用 进程同步 确保进程按特定顺序执行避免竞态条件。 互斥访问共享资源 保证只有一个进程能够访问共享资源防止数据损坏。 限制资源访问 控制同时访问某些资源的进程数量防止过多的进程占用资源。 2.2 API详解 常用的信号量相关的函数是在 POSIX 标准中定义的用于在进程间通信中创建和操作信号量。下面是一些常用的信号量函数以及信号量的应用举例 int sem_init(sem_t *sem, int pshared, unsigned int value);    - 初始化信号量。    - 参数 sem 是信号量指针pshared 表示信号量的共享方式value 是初始计数值。    - 返回值成功返回0失败返回-1。 int sem_wait(sem_t *sem);    - 对信号量执行 PWait操作。    - 参数 sem 是信号量指针。    - 返回值成功返回0失败返回-1。 int sem_post(sem_t *sem);    - 对信号量执行 VSignal操作。    - 参数 sem 是信号量指针。    - 返回值成功返回0失败返回-1。 int sem_destroy(sem_t *sem);    - 销毁信号量。    - 参数 sem 是信号量指针。    - 返回值成功返回0失败返回-1。 2.3 使用示例 ①生产者进程共享内存作为进程间通信介质 #include stdio.h #include stdlib.h #include unistd.h #include semaphore.h #include fcntl.h #include sys/mman.h#define BUFFER_SIZE 5typedef struct {int buffer[BUFFER_SIZE];int in;int out;sem_t empty;sem_t full;sem_t mutex; } shared_data_t;int main() {// 创建共享内存int shm_fd shm_open(/my_shm, O_CREAT | O_RDWR, 0666);ftruncate(shm_fd, sizeof(shared_data_t));shared_data_t *shared_data (shared_data_t *)mmap(NULL, sizeof(shared_data_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);// 初始化信号量sem_init((shared_data-empty), 1, BUFFER_SIZE);sem_init((shared_data-full), 1, 0);sem_init((shared_data-mutex), 1, 1);int data 1;while (1) {sem_wait((shared_data-empty)); // 等待缓冲区非满sem_wait((shared_data-mutex)); // 加锁shared_data-buffer[shared_data-in] data;printf(Produced: %d\n, data);data;shared_data-in (shared_data-in 1) % BUFFER_SIZE;sem_post((shared_data-mutex)); // 解锁sem_post((shared_data-full)); // 增加缓冲区内数据数量sleep(1); // 生产数据后等待一段时间}munmap(shared_data, sizeof(shared_data_t));shm_unlink(/my_shm);sem_destroy((shared_data-empty));sem_destroy((shared_data-full));sem_destroy((shared_data-mutex));return 0; } ②消费者进程 #include stdio.h #include stdlib.h #include unistd.h #include semaphore.h #include fcntl.h #include sys/mman.h#define BUFFER_SIZE 5typedef struct {int buffer[BUFFER_SIZE];int in;int out;sem_t empty;sem_t full;sem_t mutex; } shared_data_t;int main() {// 打开共享内存int shm_fd shm_open(/my_shm, O_RDWR, 0666);shared_data_t *shared_data (shared_data_t *)mmap(NULL, sizeof(shared_data_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);while (1) {sem_wait((shared_data-full)); // 等待缓冲区非空sem_wait((shared_data-mutex)); // 加锁int data shared_data-buffer[shared_data-out];printf(Consumed: %d\n, data);shared_data-out (shared_data-out 1) % BUFFER_SIZE;sem_post((shared_data-mutex)); // 解锁sem_post((shared_data-empty)); // 增加缓冲区空闲数量sleep(2); // 消费数据后等待一段时间}munmap(shared_data, sizeof(shared_data_t));close(shm_fd);return 0; } ③线程同步应用 #include stdio.h #include pthread.h #include semaphore.hsem_t semaphore1, semaphore2;void* thread1_function(void* arg) {sem_wait(semaphore1); // 等待信号量1printf(Thread 1 is executing.\n);sem_post(semaphore2); // 释放信号量2允许线程2执行return NULL; }void* thread2_function(void* arg) {sem_wait(semaphore2); // 等待信号量2确保线程1先执行printf(Thread 2 is executing.\n);sem_post(semaphore1); // 释放信号量1允许线程1再次执行return NULL; }int main() {sem_init(semaphore1, 0, 1); // 初始化信号量1为1sem_init(semaphore2, 0, 0); // 初始化信号量2为0pthread_t thread1, thread2;pthread_create(thread1, NULL, thread1_function, NULL);pthread_create(thread2, NULL, thread2_function, NULL);pthread_join(thread1, NULL);pthread_join(thread2, NULL);sem_destroy(semaphore1);sem_destroy(semaphore2);return 0; } ④线程互斥访问共享资源 #include stdio.h #include pthread.h #include semaphore.hsem_t semaphore; int shared_variable 0;void* thread1_function(void* arg) {sem_wait(semaphore); // 请求信号量shared_variable;printf(Thread 1: Incremented shared variable to %d.\n, shared_variable);sem_post(semaphore); // 释放信号量return NULL; }void* thread2_function(void* arg) {sem_wait(semaphore); // 请求信号量shared_variable--;printf(Thread 2: Decremented shared variable to %d.\n, shared_variable);sem_post(semaphore); // 释放信号量return NULL; }int main() {sem_init(semaphore, 0, 1); // 初始化信号量为1pthread_t thread1, thread2;pthread_create(thread1, NULL, thread1_function, NULL);pthread_create(thread2, NULL, thread2_function, NULL);pthread_join(thread1, NULL);pthread_join(thread2, NULL);sem_destroy(semaphore);return 0; } ⑤线程限制资源访问 #include stdio.h #include pthread.h #include semaphore.hsem_t semaphore; int resource_count 3;void* thread_function(void* arg) {sem_wait(semaphore); // 请求信号量resource_count--;printf(Thread %d: Accessed resource. Remaining resources: %d.\n, (int)arg, resource_count);sem_post(semaphore); // 释放信号量return NULL; }int main() {sem_init(semaphore, 0, 3); // 初始化信号量为3允许同时访问3个资源pthread_t threads[5];for (int i 0; i 5; i) {pthread_create(threads[i], NULL, thread_function, (void*)(i 1));}for (int i 0; i 5; i) {pthread_join(threads[i], NULL);}sem_destroy(semaphore);return 0; } 3、消息队列 3.1 概念 消息队列是一种进程间通信的机制用于在不同进程之间传递数据。它允许一个进程向消息队列发送消息而另一个进程可以从队列中读取这些消息。消息队列是一种异步通信方式进程可以通过消息队列实现数据的交换而不需要直接共享内存。 消息队列的特点包括 1. 异步通信发送者将消息发送到队列后不需要等待接收者处理完消息就可以继续自己的工作。 2. 松耦合消息队列实现了进程间的松耦合发送者和接收者之间无需直接知道彼此的存在。 3. 缓冲消息队列可以缓存一定数量的消息即使接收者暂时不可用消息也不会丢失。 4. 多对多多个进程可以同时向一个队列发送消息也可以从队列读取消息。 5. 消息优先级消息队列通常支持消息的优先级以确保重要的消息能够尽快被处理。消息队列在操作系统中是由内核维护的通常由消息队列标识符来标识不同的消息队列。 3.2 API函数 消息队列通常使用操作系统提供的API来进行创建、发送和接收消息。以下是System V消息队列的常用API函数及其详细解释 1. int msgget(key_t key, int msgflg);    - 创建或获取消息队列。    - 参数 key 是消息队列键值msgflg 是标志位如 IPC_CREAT 表示创建队列。    - 返回值成功返回消息队列标识符非负整数失败返回-1。 2. int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);    - 发送消息到消息队列。    - 参数 msqid 是消息队列标识符msgp 是指向消息结构的指针msgsz 是消息的大小msgflg 是标志位。    - 返回值成功返回0失败返回-1。 3. ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);    - 从消息队列接收消息。    - 参数 msqid 是消息队列标识符msgp 是指向消息结构的指针msgsz 是接收缓冲区大小msgtyp 是消息的类型msgflg 是标志位。    - 返回值成功返回接收的消息大小失败返回-1。 4. int msgctl(int msqid, int cmd, struct msqid_ds *buf);    - 控制消息队列属性。    - 参数 msqid 是消息队列标识符cmd 是控制命令如 IPC_RMID 表示删除队列buf 是指向 msqid_ds 结构的指针用于获取或设置属性。    - 返回值成功返回0失败返回-1。 5. key_t ftok(const char *pathname, int proj_id); pathname一个存在的文件路径名用于生成键值。通常选择一个在系统中具有唯一性的文件。 proj_id一个整数用于在 pathname 的基础上生成键值的一部分。这个值应该被选取为正整数不同的项目可以选择不同的值。 返回值返回一个 key_t 类型的键值用于后续的系统调用。如果出错返回 -1。 ftok 函数通过结合给定的文件路径名和项目标识号来生成一个键值这个键值可以被用于创建和访问共享内存、消息队列等。在实际使用中ftok 生成的键值应该在相关的进程间通信操作中保持一致。 3.3 应用代码 ①发送进程示例代码 #include stdio.h #include stdlib.h #include string.h #include sys/types.h #include sys/ipc.h #include sys/msg.hstruct message {long type;char text[50]; };int main() {key_t key;int msgid;struct message msg;// 生成键值key ftok(message_queue_example, 65);// 创建消息队列msgid msgget(key, 0666 | IPC_CREAT);// 设置消息msg.type 1;strcpy(msg.text, Hello from sender!);// 发送消息msgsnd(msgid, msg, sizeof(msg.text), 0);return 0; } ②接收进程示例代码 #include stdio.h #include stdlib.h #include string.h #include sys/types.h #include sys/ipc.h #include sys/msg.hstruct message {long type;char text[50]; };int main() {key_t key;int msgid;struct message msg;// 生成键值key ftok(message_queue_example, 65);// 获取消息队列msgid msgget(key, 0666 | IPC_CREAT);// 接收消息msgrcv(msgid, msg, sizeof(msg.text), 1, 0);printf(Received message: %s\n, msg.text);// 删除消息队列msgctl(msgid, IPC_RMID, NULL);return 0; } 4、共享内存 4.1 概念 共享内存是一种进程间通信机制允许多个进程共享同一块物理内存区域。相对于其他进程间通信方式共享内存的特点是高效、快速适用于大量数据的交换。 4.2 API ①key_t ftok(const char *pathname, int proj_id); pathname一个存在的文件路径名用于生成键值。通常选择一个在系统中具有唯一性的文件。 proj_id一个整数用于在 pathname 的基础上生成键值的一部分。这个值应该被选取为正整数不同的项目可以选择不同的值。 返回值返回一个 key_t 类型的键值用于后续的系统调用。如果出错返回 -1。 ftok 函数通过结合给定的文件路径名和项目标识号来生成一个键值这个键值可以被用于创建和访问共享内存、消息队列等。在实际使用中ftok 生成的键值应该在相关的进程间通信操作中保持一致。 ②int shmget(key_t key, size_t size, int shmflg); - 创建或获取共享内存段。 - key用于标识共享内存的键值。 - size指定共享内存段的大小。 - shmflg用于控制共享内存的标志可以包括 IPC_CREAT 来创建共享内存。 - 返回值成功时返回共享内存标识符失败时返回-1。③void *shmat(int shmid, const void *shmaddr, int shmflg); - 连接到共享内存段。 - shmid共享内存标识符。 - shmaddr指定连接地址通常设为NULL由系统决定。 - shmflg用于控制共享内存的标志。 - 返回值连接成功时返回连接地址失败时返回 (void*)-1。④int shmdt(const void *shmaddr); - 断开与共享内存的连接。 - shmaddr连接地址。 - 返回值成功时返回0失败时返回-1。⑤int shmctl(int shmid, int cmd, struct shmid_ds *buf); - 控制共享内存段的属性。 - shmid共享内存标识符。 - cmd控制命令如 IPC_RMID 用于删除共享内存。 - buf用于获取或设置共享内存段的属性。 - 返回值成功时返回0失败时返回-1。 4.3 示例代码 创建共享内存 #include stdio.h #include stdlib.h #include unistd.h #include sys/ipc.h #include sys/shm.hint main() {key_t key ftok(shared_memory_example, 65); // 生成键值int shmid shmget(key, sizeof(int), 0666 | IPC_CREAT); // 创建共享内存if (shmid -1) {perror(shmget);exit(1);}int *shared_data (int*)shmat(shmid, NULL, 0); // 连接到共享内存*shared_data 10; // 设置共享数据printf(Shared data set to %d\n, *shared_data);shmdt(shared_data); // 断开与共享内存的连接return 0; } 使用共享内存 #include stdio.h #include stdlib.h #include unistd.h #include sys/ipc.h #include sys/shm.hint main() {key_t key ftok(shared_memory_example, 65); // 生成键值int shmid shmget(key, sizeof(int), 0666); // 获取共享内存if (shmid -1) {perror(shmget);exit(1);}int *shared_data (int*)shmat(shmid, NULL, 0); // 连接到共享内存printf(Shared data read: %d\n, *shared_data);shmdt(shared_data); // 断开与共享内存的连接return 0; } 5、套接字 5.1 概念 套接字Socket是一种用于实现网络通信的编程接口它提供了一种机制使得不同计算机之间可以通过网络进行数据交换。套接字允许进程在不同主机上的应用程序通过网络进行通信从而实现分布式系统和客户端-服务器模型。         套接字提供了一组API函数用于在应用程序中创建、连接、发送和接收数据。它是网络编程的基础用于实现各种通信协议如TCP传输控制协议和UDP用户数据报协议。 5.2 API 1. int socket(int domain, int type, int protocol); - 创建一个新的套接字。 - domain指定套接字的协议族如 AF_INET 表示IPv4。 - type指定套接字的类型如 SOCK_STREAM 表示面向连接的流套接字TCP。 - protocol指定使用的传输协议通常设为0以便自动选择合适的协议。 - 返回值成功时返回套接字文件描述符失败时返回-1。2. int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); - 将一个本地地址与套接字绑定。 - sockfd套接字文件描述符。 - addr指向本地地址结构的指针。 - addrlen本地地址结构的大小。 - 返回值成功时返回0失败时返回-1。3. int listen(int sockfd, int backlog); - 将套接字设为监听模式准备接受连接请求。 - sockfd套接字文件描述符。 - backlog等待连接的队列长度。 - 返回值成功时返回0失败时返回-1。4. int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); - 接受一个连接请求创建一个新的套接字用于与客户端通信。 - sockfd监听套接字文件描述符。 - addr用于存储客户端地址的结构指针。 - addrlen客户端地址结构的大小。 - 返回值成功时返回新创建的套接字文件描述符失败时返回-1。5. int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); - 建立与远程服务器的连接。 - sockfd套接字文件描述符。 - addr指向远程服务器地址结构的指针。 - addrlen远程服务器地址结构的大小。 - 返回值成功时返回0失败时返回-1。6. ssize_t send(int sockfd, const void *buf, size_t len, int flags); - 发送数据。 - sockfd套接字文件描述符。 - buf指向待发送数据的缓冲区。 - len待发送数据的大小。 - flags选项标志通常设为0。 - 返回值成功时返回发送的字节数失败时返回-1。7. ssize_t recv(int sockfd, void *buf, size_t len, int flags); - 接收数据。 - sockfd套接字文件描述符。 - buf用于存储接收数据的缓冲区。 - len缓冲区的大小。 - flags选项标志通常设为0。 - 返回值成功时返回接收的字节数连接关闭时返回0失败时返回-1。8. int close(int sockfd); - 关闭套接字连接。 - sockfd套接字文件描述符。 - 返回值成功时返回0失败时返回-1。 5.3 示例代码 服务端 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/types.h #include sys/socket.h #include netinet/in.hint main() {int sockfd, newsockfd, portno, clilen;char buffer[256];struct sockaddr_in serv_addr, cli_addr;int n;// 创建套接字sockfd socket(AF_INET, SOCK_STREAM, 0);if (sockfd 0) {perror(Error opening socket);exit(1);}bzero((char *)serv_addr, sizeof(serv_addr));portno 12345;serv_addr.sin_family AF_INET;serv_addr.sin_addr.s_addr INADDR_ANY;serv_addr.sin_port htons(portno);// 绑定套接字到地址if (bind(sockfd, (struct sockaddr *)serv_addr, sizeof(serv_addr)) 0) {perror(Error on binding);exit(1);}// 监听连接listen(sockfd, 5);clilen sizeof(cli_addr);newsockfd accept(sockfd, (struct sockaddr *)cli_addr, clilen);if (newsockfd 0) {perror(Error on accept);exit(1);}// 读取客户端发送的消息bzero(buffer, 256);n read(newsockfd, buffer, 255);if (n 0) {perror(Error reading from socket);exit(1);}printf(Message from client: %s\n, buffer);// 关闭连接close(newsockfd);close(sockfd);return 0; } 客户端 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include netdb.hint main() {int sockfd, portno, n;struct sockaddr_in serv_addr;struct hostent *server;char buffer[256];portno 12345;sockfd socket(AF_INET, SOCK_STREAM, 0);if (sockfd 0) {perror(Error opening socket);exit(1);}// 获取服务器信息server gethostbyname(localhost);if (server NULL) {fprintf(stderr, Error, no such host\n);exit(1);}bzero((char *)serv_addr, sizeof(serv_addr));serv_addr.sin_family AF_INET;bcopy((char *)server-h_addr, (char *)serv_addr.sin_addr.s_addr, server-h_length);serv_addr.sin_port htons(portno);// 连接到服务器if (connect(sockfd, (struct sockaddr *)serv_addr, sizeof(serv_addr)) 0) {perror(Error connecting);exit(1);}printf(Please enter the message: );bzero(buffer, 256);fgets(buffer, 255, stdin);n write(sockfd, buffer, strlen(buffer));if (n 0) {perror(Error writing to socket);exit(1);}// 关闭套接字close(sockfd);return 0; }
http://www.zqtcl.cn/news/12445/

相关文章:

  • 网站建设不能使用的广告违禁词企业展示类网站模板
  • 大型网站怎么做优化xampp wordpress 手机访问
  • 网站服务器无响应是怎么回事seo的网站特征
  • 网站建设公司方唯wordpress 统计字数
  • 如何用ps做网站平面图开发微信公众号公司
  • 西安做北郊做网站教育平台
  • 四川建设人才官方网站wordpress访客显示
  • 常州网站建设系统综合商城网站程序
  • 电子商务网站建设源码wordpress显示多页选项
  • 选择建设网站公司要注意什么问题网站正在建设中 英语翻译
  • 制作一个.net网站需要网站标签的作用
  • 哪家网站雅虎全球购做的好建设简单网站的图纸
  • 网站开发有名的公司wordpress文章阅读量
  • 中国建设银行网站快速查询wap和app
  • 天河网站建设公司排名人工智能软件定制
  • 做网站选择什么相机如何制作一个网页链接
  • 做网站赚几百万小型企业网站模板
  • 金融集团网站模板免费咨询图片大全
  • 哪个网站做logo好什么网络游戏比较好玩
  • 袜子网站建设规划书创意设计说明范文
  • 建设一个征婚网站的程序进入网站后台管理系统
  • 电子业网站建设购物app排行榜
  • 宁夏建设投资集团公司网站wordpress如何导航网站模板下载
  • 做网站三剑客白种女人做爰网站
  • 建同城购物网站经历给人做网站挣钱吗
  • 中小企业网站制作手机电子商务网站建设问卷调查
  • 新网站如何做百度百科可信网站申请
  • 建网站公司用什么网站程序做网站参考线怎么拉
  • wap建站程序合集一建报考专业
  • 什么网站做学校设计黄州做网站的