導航:首頁 > 操作系統 > htonslinux

htonslinux

發布時間:2022-08-17 09:52:27

❶ 網路編程linux如何實現客戶端回射

這個可以用python寫個程序,讓伺服器端一直監聽某個埠,比如監聽在9527埠上,然後用客戶端去訪問指定的ip+埠,就能連接到伺服器上

❷ Linux下C語言socket編程

socket編程一般是基於tcp或者udp協議來寫的,你的問題很抽象,我不知道你要的是基於tcp還是udp的socket編譯。我把相對難的基於tcp協議的socket編譯給你吧。你想看懂我的代碼需要知道tcp的三次握手機制。否則我寫了注釋,你看代碼也有點困難。 ////服務端的代碼
1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/socket.h>
4 #include <unistd.h>
5 #include <netinet/in.h>
6 #include <sys/stat.h>
7 #include <stdlib.h>
8 #include <arpa/inet.h>
9
10 #define LOCAL_PORT 1234
11 #define MAX_LEN 512
12 #define MAX_NUM 5
13
14 int main(int argc, char *argv[])
15 {
16 int sock_fd, sock_data;
17 int ret, len_addr;
18 char buf[MAX_LEN];
19 ssize_t len;
20 struct sockaddr_in local_addr, remote_addr;
21
22 sock_fd = socket(AF_INET, SOCK_STREAM, 0); //創建套接字,sock_fd是套接字描述符,類似我們的身份證號碼
23 if (sock_fd < 0)
24 {
25 perror("socket()");
26 return sock_fd;
27 }
28
29 local_addr.sin_family = AF_INET;// 協議族,ipv4
30 local_addr.sin_port = htons(LOCAL_PORT);// 把伺服器埠轉換成網路位元組序
31 local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");//把字元串形式的ip轉換成網路位元組序
32
33 ret = bind(sock_fd, (struct sockaddr *)&local_addr, (size_t)sizeof(local_addr));// 把sock_fd和本機ip,埠邦定
34 if (ret < 0)
35 {
36 perror("bind()");
37 close(sock_fd);
38 return ret;
39 }
40
41 ret = listen(sock_fd, MAX_NUM);//監聽socket
42 if (ret)
43 {
44 perror("listen()");
45 close(sock_fd);
46 return ret;
47 }
48
49 memset(buf, 0, MAX_LEN);
50
51 len_addr = sizeof(remote_addr);
52
53 sock_data = accept(sock_fd, (struct sockaddr *)&remote_addr, (socklen_t *)&len_addr);//接受客戶端的連接
54 if (ret < 0)
55 {
56 perror("accept()");
57 close(sock_fd);
58 return ret;
59 }
60
61 while (1)
62 {
63 int slen;
64 len = recv(sock_data, buf, MAX_LEN, 0);//接受客戶端的數據
65 if (len < 0)
66 {
67 perror("recv()");
68 close(sock_data);
69 close(sock_fd);
70 return len;
71 }
72 printf("%s\n", buf);
73
74 slen = send(sock_data, "congratulation!", 15, 0);//向客戶端發送數據
75 if (slen <= 0)
76 {
77 printf("slen = %d\n", slen);
78 perror("send()");
79 close(sock_data);
80 close(sock_fd);
81 return slen;
82 }
83 sleep(1);
84 }
85
86 close(sock_data);
87 close(sock_fd);
88
89 return 0;
90 }
////////////客戶端的代碼 1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/socket.h>
4 #include <unistd.h>
5 #include <netinet/in.h>
6 #include <sys/stat.h>
7 #include <stdlib.h>
8 #include <arpa/inet.h>
9
10 #define REMOTE_PORT 1234
11 #define MAX_LEN 512
12
13 int main(int argc, char *argv[])
14 {
15 int sock_fd, ret;
16 int len;
17 char buf[MAX_LEN];
18 struct sockaddr_in local_addr, remote_addr;
19
20 sock_fd = socket(AF_INET, SOCK_STREAM, 0);
21 if (sock_fd < 0)
22 {
23 perror("socket()");
24 return sock_fd;
25 }
26
28 local_addr.sin_family = AF_INET;
29 local_addr.sin_addr.s_addr = htonl(INADDR_ANY); //自動獲取本機的ip地址
30 local_addr.sin_port = htons(0); //隨機選取可用的埠,並不是指定埠為0
31
33 remote_addr.sin_family= AF_INET;
34 remote_addr.sin_port = htons(REMOTE_PORT);
35 ret = inet_aton("127.0.0.1", &remote_addr.sin_addr);
36
38 ret = bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(local_addr)); //把本機的ip,port和socket綁定
39 if (ret < 0)
40 {
41 perror("bind() !");
42 close(sock_fd);
43 return ret;
44 }
45
47 ret = connect(sock_fd, (struct sockaddr *)&remote_addr, (socklen_t)sizeof(remote_addr)); //把本機的socket和對方的port,ip建立連接
48 if (ret < 0)
49 {
50 perror("connect()");
51 close(sock_fd);
52 return ret;
53 }
54
55 memset(buf, 0, MAX_LEN);
56
57 while (1)
58 {
59 int i;
60 // len = send(sock_fd, buf, (size_t)MAX_LEN, 0);
61 len = send(sock_fd, "hello", 6, 0);
62 if (len <= 0)
63 {
64 perror("send()");
65 close(sock_fd);
66 return ret;
67 }
68
69 // printf("%d-->bytes send!\n", len);
70 sleep(1);
71
72 len = recv(sock_fd, buf, MAX_LEN, 0);
73 if (len <= 0)
74 {
75 perror("recv()");
76 close(sock_fd);
77 return ret;
78 }
79
80 for (i = 0; i < len; i++)
81 {
82 printf("%c", buf[i]);
83 }
84 printf("\n");
85 }
86
87 close(sock_fd);
88
89 return 0;
90 }
你把服務端和客戶端這兩個程序分別保存為server.c和client.c。然後編譯gcc server.c -o server,gcc client .c -o client。運行時先運行服務端,用命令./server,再運行客戶端,用命令./client。 注意運行命令是「點 斜杠」,「點」表示當前目錄。

❸ linux下socket編程,菜鳥求解。。。

linux-u4p5:~/test/socket/server # ./client
connect ok,waiting for the server's message back
程序好像沒看出問題來啊
會不會是防火牆設置問題?

❹ linux下的 socket編程問題!

第一個問題:

對,是那樣的,用open打開文件,用read讀取文件,在發送給對方,接收方接收到後,寫入文件就可以了。不過在這個過程中最好別用字元串函數,除非你很熟悉。

第二個問題

首先你得去搞清楚什麼是線程,什麼是進程,fork出來的叫進程,pthread_create出來的才叫線程。伺服器有很多種模型(多進程,多線程,select,epoll模型,這個我的blog上有,famdestiny.cublog.cn),不一定要用多進程。

給你寫了個代碼,自己先看看:

注意,在自己的目錄下創建一個叫pserverb的文件,程序會把這個文件復製成test文件。你可以自己根據需要改改

server:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SERV_PORT 5358
#define MAX_CONN 10
#define BUF_LEN 1024

void str_echo(FILE *fp, int sockfd){
ssize_t nread;
int file_fd;
char buf[BUF_LEN] = {0};

file_fd = open("test", O_WRONLY | O_TRUNC | O_CREAT, 0755);
while(1) {
bzero(buf, BUF_LEN);
if((nread = read(sockfd, buf, BUF_LEN)) == -1) {
if(errno == EINTR) {
continue;
}
else {
printf("readn error: %s\n", strerror(errno));
continue;
}
}
else if (nread == 0) {
break;
}
else {
printf("%s\n", buf);
write(file_fd, buf, nread);
}
}
close(file_fd);
}

void sig_chld(int sig){
pid_t pid;
int state;
while((pid = waitpid(-1, &state, WNOHANG)) > 0){
printf("child process %d exited.", pid);
}
return;
}

int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t cliaddrlen;
pid_t childpid;
struct sockaddr_in servaddr, cliaddr;

if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("socket error: %s\n", strerror(errno));
return 0;
}

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
printf("bind error: %s\n", strerror(errno));
return 0;
}

if(listen(listenfd, MAX_CONN) == -1){
printf("listen error: %s\n", strerror(errno));
return 0;
}

signal(SIGCHLD, sig_chld);

while(1){
cliaddrlen = sizeof(cliaddr);
if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen)) == -1){
if(errno == EINTR){
continue;
}
else{
printf("accept error: %s\n", strerror(errno));
continue;
}
}

if((childpid = fork()) == 0){
close(listenfd);
str_echo(stdin, connfd);
exit(0);
}
else if(childpid > 0){
close(connfd);
}
else{
printf("fork error!\n");
continue;
}
}
}

client:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define SERV_ADDR "127.0.0.1"
#define SERV_PORT 5358
#define BUF_LEN 1024

void str_cli(char *path, int sockfd)
{
char sendbuf[BUF_LEN] = {0};
int fd, n;

if((fd = open("./pserverb", O_RDONLY)) == -1){
printf("%s\n", strerror(errno));
exit(0);
}
while((n = read(fd, sendbuf, BUF_LEN)) != 0) {
if(n < 0){
printf("%s\n", strerror(errno));
exit(0);
}
write(sockfd, sendbuf, n);
bzero(sendbuf, BUF_LEN);
}
close(fd);
return;
}

int main(int argc, char **argv)
{
int fd;
struct sockaddr_in servaddr;

fd = socket(AF_INET, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(SERV_ADDR);
servaddr.sin_port = htons(SERV_PORT);

if (connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf("connect error: %s\n", strerror(errno));
return 0;
}

str_cli(argv[1], fd);
return 0;
}

❺ linux socket是什麼意思

基於Linux的SOCKET編程。

❻ 如何實現在Linux下創建服務程序

Linux系統能提供強大可靠的網路服務,並有管理程序對服務進行管理。例如我們熟悉的Web、FTP和電子郵件等,它們既可以單獨運行,也可以被守護進程inetd調用,而且運行得都非常好。但我們不能僅停留在贊嘆中,下面就給出兩個服務程序程序和一個客戶程序的例子,介紹服務程序和客戶程序之間是如何溝通的。另外還要編輯配置一些文件,讓服務程序也能接受服務管理程序管理。

這兩個服務程序功能相同,但一個是獨立服務程序,另一個是被inetd調用的服務程序。這是TCP/IP網路服務的兩大類,這里將兩個程序放在一起是為了比較程序結構和運行方式。兩服務程序都在Red Hat Linux 7.1和TurboLinux 7.0上調試通過。

獨立伺服器

TCP和UDP是兩大TCP/IP數據傳輸方式,套介面是建立伺服器客戶機連接的機制,首先介紹它們建立通信聯系的過程,然後給出一個TCP服務程序例子。

1.TCP套介面通信方式

對於TCP伺服器端,服務程序首先調用建立套介面的函數socket(),然後調用綁定服務IP地址和協議埠號函數bind()。綁定成功後調用被動監聽函數listen()等待客戶連接,還要調用獲取連接請求函數accept(),並一直阻塞到客戶連接請求的到達,這個函數獲取客戶機IP地址和協議埠號。

對於TCP客戶端,客戶程序啟動後後調用建立套介面函數socket(),然後調用連接函數connect(),此函數與伺服器通過三次握手建立連接。

伺服器和客戶機建立連接後,就可以使用讀函數read()和寫函數write()收發數據了。數據交換完成後便各自調用關閉套介面函數close()刪除套介面。TCP套介面通信方式見圖1所示。

圖1 TCP套介面通信方式

2.UDP套介面通信方式

UDP程序與TCP的區別是無需建立連接。伺服器首先啟動,然後等待用戶請求。客戶機啟動後便直接向伺服器請求服務,伺服器接到請求後給出應答。

對於UDP伺服器端,服務程序首先調用套介面函數socket(),然後調用綁定IP地址和協議埠號函數bind()。之後調用函數recvfrom()接收客戶數據,調用sendto()向客戶發送數據。

對於UDP客戶端,客戶機程序啟動後調用套介面函數socket(),然後調用sendto()向伺服器發送數據,調用recvfrom()接收伺服器數據。

雙方數據交換成功後,各自調用關閉套介面函數close()關閉套介面。UDP套介面通信方式見圖2所示。

圖2 UDP套介面通信方式

下面給出獨立服務程序的例子。這個程序雖然簡單,但是與復雜程序有著相同的結構。

//程序名:server.c
//功能:伺服器從客戶機讀入一個字元,並將排在此字元後面的字元回送客戶機
//伺服器埠:9000
#include "sys/types.h"
#include "sys/socket.h"
#include "stdio.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include "unistd.h"
int main()
{
int pid; //用於存放fork()執行結果
int server_sockfd,client_sockfd; //用於伺服器和客戶機套介面描述符
int bind_flag,listen_flag; //用於存放bind()和listen()執行結果
int server_address_length,client_address_length; //作為伺服器客戶機地址長變數
struct sockaddr_in server_address; //作為伺服器地址結構變數(含地址和埠)
struct sockaddr_in client_address; //作為客戶機地址結構變數(含地址和埠)
if((pid=fork())!=0) //用fork()產生新進程
exit(0) ;
setsid() ; //以子進程開始下面的程序

函數socket(),創建一個套介面,成功則返回套介面描述符。

server_sockfd=socket(AF_INET,SOCK_STREAM,0);
if(server_sockfd<0)
{
printf(「socket error /n」);
exit(1);
}
server_address.sin_family=AF_INET;

函數htonl()用於將32位主機位元組順序轉換為網路位元組順序,其中參數INADDR_ANY表示任何IP地址。

server_address.sin_addr.s_addr=htonl(INADDR_ANY);

函數htons()用於將16位主機位元組順序轉換為網路位元組順序,其中的參數是綁定的埠號,讀者可根據環境自行改動,目的是不與其它服務埠沖突。

server_address.sin_port=htons(9000);
server_address_length=sizeof(server_address);

函數bind()用於綁定本地地址和服務埠號,若調用成功返回值為0。

bind_flag=bind(server_sockfd,/
(struct sockaddr *)&server_address,/
server_address_length);
if(bind_flag<0)
{
printf(「bind error /n」);
exit(1);
}

函數listen(),指明伺服器的隊列長度,被動等待客戶連接,調用成功返回值為0。

listen_flag=listen(server_sockfd,5);
if(listen_flag<0)
{
printf(「listen error /n」);
exit(1);
}

while(1)
{
char ch;

函數accept()等待和獲取用戶請求,為每個新連接請求創建一個新的套介面,調用成功返回新套介面描述符。

client_sockfd=accept(server_sockfd,/
(struct sockaddr *)&client_address,/
&client_address_length);

函數read()和write()用於在伺服器和客戶機之間傳送數據,調用成功返回讀和寫的位元組數。

函數close(),用於程序使用完一個套介面後關閉套介面,調用成功返回值0。其中的參數為accept()創建的套介面的描述符client_sockfd。

read(client_sockfd,&ch,1);
printf(「cli_ch=%c」,ch);
ch++;
write(client_sockfd,&ch,1);

close(client_sockfd);
}
}

程序完成後就可以使用命令進行編譯。在命令行中輸入「gcc -o server server.c」,將server.c編譯成可執行程序server,這時便可用客戶程序進行測試。在命令行執行「./server」啟動服務程序,執行「netstat -na」查看有無server的服務埠。如果存在,則執行下面編寫的客戶程序「./client」。不過這僅是手工啟動的方法,下面給出用服務管理程序管理server程序的方法。只要在目錄/etc/rc.d/init.d下放入服務程序的腳本就能被服務程序讀到。在命令行執行「touch server」創建文件server,並將文件屬性改成可執行。在管理程序中並不能看到此服務名,腳本文件必須有一些結構才能被管理程序認為是服務程序腳本。

為了減少工作量,拷貝/etc/rc.d/init.d下腳本httpd,將拷貝腳本名命名為server,然後對其編輯。

(1)執行「cp httpd server」。

(2)用文本編輯器vi(其它編輯器亦可)將server打開進入編輯狀態。首先用字元串server替換httpd。然後找到daemon server行,如果編寫的程序放在變數PATH目錄中,不需要修改此行;如果把服務程序放在其它目錄中,就要寫服務的全路徑。例如程序在/root的目錄中,就要寫成daemon /root/server,還要刪除「rm -f /var/run/server.pid」這一行。

(3)執行「chmod 755 server」,將server屬性設定為可執行。

此時就可以用chkconfig、ntsysv等工具,在希望的運行級中增加這個新服務程序,然後測試客戶機與伺服器能否通信。

被xinetd調用的服務程序

在Linux系統中,有很多服務是被xinetd(較早版本使用的是inetd)超級守護伺服器啟動的。其實凡是基於TCP和UDP的服務都可使用超級守護進程啟動,只是在服務量很大影響效率的情況下不被採用。

1.依賴xinetd啟動的服務建立通信過程

為了與獨立伺服器程序比較,我們看一下依賴xinetd的伺服器是如何啟動的。

(1)xinetd啟動時讀取/etc/xinetd目錄中的文件(早期版本為/etc/inetd文件),根據其中的內容給所有允許啟動的服務創建一個指定類型的套介面,並將套介面放入select()中的描述符集合中。

(2)對每個套介面綁定bind(),所用的埠號和其它參數來自/etc/xinetd目錄下每個服務的配置文件。

(3)如果是TCP套介面就調用函數listen(),等待用戶連接。如果是UDP套介面,就不需調用此函數。

(4)所有套介面建立後,調用函數select()檢查哪些套介面是活動的。

(5)若select()返回TCP套介面,就調用accept()接收這個連接。如果為UDP,就不需調用此函數。

(6)xinetd調用fork()創建子進程,由子進程處理連接請求。

◆ 子進程關閉所有其它描述符,只剩下套介面描述符。這個套介面描述符對於TCP是accept()返回的套介面,對於UDP為最初建立的套介面。然後子進程連續三次p()函數,將套介面描述符復制到0、1和2,它們分別對應標准輸入、標准輸出和標准錯誤輸出,並關閉套介面描述符。

◆ 子進程查看/etc/xinetd下文件中的用戶,如果不是root用戶,就用調用命令setuid和setgid將用戶ID和組ID改成文件中指定的用戶。

(7)對於TCP套介面,與用戶交流結束後父進程需要關閉已連接套介面。父進程重新處於select()狀態,等待下一個可讀的套介面。

最後調用配置文件中指定的外部服務程序,外部程序啟動後就可與用戶進行信息傳遞了。

2.為xinetd編寫專門的服務程序

除了獨立服務程序能被xinetd啟動外,還可以為xinetd編寫專門的程序。此處的例子程序與上面server.c功能相同。不過兩者的程序區別是很大的,此例的代碼僅相當於上面傳輸數據的部分。我們還將程序名定為server.c,所以不能放在相同目錄中,同名僅是為了和上面程序對照。

#include "unistd.h"
int main()
{
char ch;
read(0,&ch,1);
ch++;
write(1,&ch,1);
}

將程序編譯成可執行文件,並做些設置就可被xinetd啟動。注意不要和上面的獨立服務程序server一起啟動,因為客戶程序寫得比較簡單,訪問的是固定埠,伺服器都設成了相同的埠號。

(1)編輯/etc/services文件,在行末增加一條記錄:

server 9000/tcp

(2)在目錄/etc/xinetd.d下編寫文件server,內容為:

service server
{
disable = no
socket_type = stream
protocol = tcp
wait = no
user = root
server = /home/test/server (此處設置成自己程序所在的目錄)
}

如果使用的是較早版本,則需在/etc/inetd.conf文件中添加下面的行:

server tcp nowait root /path/to/yourdirectory/server

(3)執行/etc/rc.d/initd.d/xinetd restart重新啟動xinetd伺服器。早期版本執行/etc/rc.d/initd.d/inetd restart重新啟動inetd。

(4)執行netstat -an查看有沒有server程序使用的埠號,如果有就可使用下面客戶機程序進行測試了。

客戶機程序

下面就客戶機函數做一簡單介紹。

//程序名client.c
/*功能:從客戶的控制台輸入一個字元,然後將這個字元送到伺服器,並將伺服器返回的字元顯示出來*/
#include "sys/types.h"
#include "sys/socket.h"
#include "stdio.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include "unistd.h"
int main()
{
int sockfd;//
int address_len;
int connect_flag;
struct sockaddr_in address;
int connect_result;
char client_ch,server_ch;

函數socket()用於建立一個套介面,創建成功返回套介面描述符。

sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
printf(「sockfd error /n」);
}
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr(「192.168.0.1」);/*讀者根據自己環境改成伺服器地址*/
address.sin_port=htons(9000);

address_len=sizeof(address);

函數connect()用於與伺服器建立一個主動連接,調用成功返回值為0。

connect_flag=connect(sockfd,(struct sockaddr *)&address,address_len);

if(connect_flag==-1)
{
perror(「client」);
exit(1);
}
printf(「Input a character :」);

函數scanf()用於從控制台輸入一個字元,並將字元存入client_ch的地址。函數write()和read()用於傳輸數據。函數printf()在客戶機屏幕上顯示伺服器傳回的字元。函數close()關閉套介面。

scanf(「%c」,&client_ch);
write(sockfd,&client_ch,1);
read(sockfd,&server_ch,1);
printf(「character from server : %c/n」,server_ch);
close(sockfd);
exit(0);
}

執行命令「gcc -o client client.c」,將client.c編譯成client。執行「./client」,在程序提示下輸入一個字元,就能看到伺服器傳回的字元。

以上介紹的僅是簡單的例子。平時見到的服務程序遠比它復雜,而且很多是多協議服務程序或是多協議多服務程序。多協議服務程序就是在main()中分別創建供服務的TCP和UDP套介面。為每個服務分別寫出相應程序好處是便於控制,但是這樣每個服務都啟動兩個伺服器,而它們的演算法響應是一樣的,就要耗費不必要的資源,並且出了問題排錯也較困難。多服務是將不同的服務集成在一起由一個程序完成,可用一個數組表示服務,數組中的每一項表示某協議某服務的一種,這樣很容易擴展程序的服務功能。

閱讀全文

與htonslinux相關的資料

熱點內容
千聊免費課程可以重新加密嗎 瀏覽:507
python能代替php嗎 瀏覽:252
phpexcel樣式 瀏覽:265
安卓手機有沒有什麼軟體可以阻止彈廣告的 瀏覽:306
linux區域網搭建伺服器 瀏覽:690
python編譯器mac 瀏覽:293
windows的doc命令 瀏覽:463
nfc全加密門禁卡 瀏覽:636
身份信息被加密 瀏覽:482
我的鹽城app怎麼添加不了家庭成員 瀏覽:493
php商城並發 瀏覽:348
熊貓繪畫app怎麼做出大佬的筆刷 瀏覽:603
雲存儲伺服器知識 瀏覽:461
伺服器cpu是什麼指令集 瀏覽:591
糖貓t10怎麼安裝app 瀏覽:992
電腦加密u盤怎麼使用 瀏覽:518
linux如何升級php版本升級 瀏覽:841
二級程序員c語言難度 瀏覽:353
批處理編譯qt 瀏覽:67
鐵友app怎麼查詢機票訂單 瀏覽:197