之前介紹過如何讓JAVA執行外部的指令。但若程式希望等待外部的指令執行完後,再繼續執行原來的程式,我們可以利用Process類別的waitFor()指令。waitFor()會讓目前的thread等待,直到Process物件終止才會繼續開始。
Runtime rt = Runtime.getRuntime();
try {
Process proc = rt.exec(new String[] {"..." } );
proc.waitFor(); //等待proc完成
}
catch(Exception ex) {
ex.printStackTrace();
}
2007年11月29日 星期四
waitFor
2007年11月26日 星期一
Linphone-2.0.0安裝失敗
由於實驗一直不是很順利,所以就逛逛Linphone的網頁,才發現近期已經更新到2.0.0版,改了蠻多的東西,而且也可以處理re-INVITE的訊息。於是心中閃過一個念頭就是「要不要將UA改用linphone」。
二話不說,馬上就下載原始碼自行編譯,原以為應該可以很順利的,沒想到困難重重,一堆軟體要裝也就算了,在make過程中又出現一些error。所以也請建霖裝在Fedora試試,沒想到竟然成功裝好了,讓我充滿期待。只不過,事情並沒那麼單純,視窗介面竟然弄不出來,只有文字模式,怎麼會這樣呢?
所以,還是乖乖的弄我的MjSIP吧!
Concurrent Server
Server可以分為兩種型態,iterative和concurrent。
iterative server一次服務一個使用者,所以若其中某個使用者的服務時間過久,會影響到整個效能。而concurrent server則是可以同時服務多個使用者,最簡單的方法可以利用fork來產生child process來達成此目的。下面則為簡單的範例。
pid_t pid;
int listenfd, connfd;
listenfd = socket( ... );
bind(listenfd, ... );
listen(listenfd, 5);
for (; ;) {
connfd = accept (listenfd, ... );
if((pid = fork()) == 0) {
close(listenfd);
handle the connection
close(connfd);
exit(0);
}
close(connfd); // 由於fork產生的child process會讓connfd的reference counter多1,要記得關掉
}
2007年11月25日 星期日
Ping的換手小測試
之前做SIP換手實驗的數據,結果與預期有甚大的落差,於是決定先把問題簡單化,再慢慢來擴大。於是就選擇用Ping程式先來測試一下換手的過程。
先寫簡單的shell script,把要進行的步驟寫起來,包括換AP以及設定新IP。同時間,也利用抓封包的軟體來檢驗實驗的結果。
一開始測試的結果,換手的時間還是很大。仔細看了一下抓下來的封包,發現Echo request的確是用新的IP當來源繼續送,但卻沒有Echo reply回來。直到出現NA、NS封包完成後,Echo reply就回來了。這對NA、NS是在要求對方的MAC位址,類似IPv4的ARP。
於是就猜測是Mobile Node到新網路不知道新的AP的MAC,而新AP也不知道MN的MAC。所以就修改了一下之前的shell script,再換手後,馬上在neighbor cache加上AP的MAC,同時間也在AP加上MN的MAC。
經過再次的實驗,換手時間降低了不少。
2007年11月24日 星期六
Debian編譯核心
用Debian的方式編譯核心,可以將編好的核心變成deb檔,方便管理
首先,下安裝編譯時需要的工具
# apt-get install fakeroot kernel-package libncurses5-dev bzip wget build-essential
下載所需的核心並解壓縮在/usr/src裡
# cd /usr/src
# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.8.tar.bz2
# tar jxvf linux-2.6.23.8.tar.bz2
# cd /usr/src linux-2.6.23.8
開始編譯核心
# make menuconfig
# make-kpkg clean
# fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers
若無任何錯誤訊息,代表已經成功編譯完成,在/usr/src會出現兩個deb檔
# dpkg -i linux-image-2.6.23.8-custom_2.6.23.8-custom-10.00.Custom_i386.deb
# dpkg -i linux-headers-2.6.23.8-custom_2.6.23.8-custom-10.00.Custom_i386.deb
重開機即可
fork
如何寫一個concurrent server?我們可以使用fork這個function來達成,定義於"unistd.h",用法如下:
pid_t fork(void);
呼叫fork()會產生一個child process,在呼叫fork()指令之前所有parent process開啟的descriptors會與child processs共享。至於如何分辨parent還是child,則依呼叫fork()後的回傳值決定,parent會收到child的Process ID,而child則會收到0。因為,兒子只有一個父親,只要呼叫getppid即可取得父親的PID,而父親可能會有很多的兒子,所以需要記錄每一個兒子的PID。
fork有兩種使用方法:
- Process複製自己一份,讓其中一個處理某一個運算,另一個則是做其它事。
- Process想執行其它程式,當呼叫fork時會複製一份child process,然後child process執行exec用新程式來取代目前的程式。
2007年11月20日 星期二
到警局說明(11/19/07)
無妄之災
星期六的晚上接到媽打來的電話,第一句就是問我說我有沒有跟別人結怨或是什麼?聽得我是一頭霧水。接著又說我被告詐欺,說收到警察局寄來的通知單要我到警察局說明,而我第一個直覺就說該不會又是詐騙集團吧?但講完馬上換我爸跟我講,這次就感覺有點情況不對了,爸說是真的。真是晴天霹靂啊!沒想到我竟成為了詐欺犯,我總覺得我應該也只有被詐騙的份吧。爸就把通知單傳真到我台中宿舍樓下的7-11。看到通知單真是傻眼,我這個人本來就很容易緊張,一遇到事情就會很心煩,想來想去,就是想不出個所以然,我到底詐欺了什麼?真讓人心煩。爸就叫我別緊張,要是不是我們做的事,就不要怕。約定的時間是星期一下午兩點到台中市警察局第六分局,爸叮嚀我找個朋友一起去,於是我就先約了小書書星期一一起去,小書書很爽快的就答應了,真感謝小書書。
星期日晚上,爸又來了一通電話,問我需不需要爸來台中陪我一起去,其實當時我一點主意也沒有,但我想應該沒那麼嚴重吧,先聽聽到底是什麼事,再做打算,所以我就告訴爸不用了,我和同學去就好了。在同一個時間,傑宇很熱心的幫我聯絡到一個好像是身份被盜用被告詐欺的過來人,他提供了許多意見給我參考。在這,我也要先跟傑宇說聲感謝,一直幫我找資料。
星期一一大早,我就來到了實驗室,想說先打個電話問承辦員警,到底事情的來龍去脈是什麼,只可惜,沒能聯絡到他。大概快十二點左右,又接到了媽打來的電話,說是爸已經開車來台中的途上,說還是擔心我,要一起去。此時的氣氛感到愈來愈多的不安與焦慮,還從未進去過警察局耶,沒想到第一次進去會是被告的身份。我和小書書大概一點十五左右到,而我爸媽也大約在同一個時間到了台中市警察局第六分局。於是就一起走進了警察局,一開始,裡面的員警是說我們太早來,不是約兩點嗎,於是叫我們先在外面等。等來等去,時間一分一秒的過去,沒想到竟然到了三點多,承辦員警才出現,這....實在是不予置評。
該來的還是要來,承辦員警就把我叫了進去。一開始就問我說你知不知道你為什麼會來這?唉,這句話我還更想要問耶!整個問答當中,問了你有幾個帳戶、郵局的局號、有沒有遺失或借別人證件。之後,重點來了,拿出來一個應該是台灣大哥大的門號資料,警察一開口就說這是不是你的手機,一切終於知道問題之所在了,身份被盜用去辦了門號。而我當然很直接了斷的說不是我的,可是員警卻一直在質疑我,然後又說這帳單地址都是填我家,怎麼可能有誤。這,明明沒收到就沒收到,我就說家裡的帳單都是我媽在收的,於是他就叫我叫我媽進去,他就把問我的問題又問了我媽一次,當然,我媽的答案一定跟我一樣,誰會去付錢去繳不是自己家人申請的門號。最後,也就結束了問談。
結束之後,大家突然想到,員警是說那隻門號是用預付卡辦理,當然沒有帳單囉,這不是在搞笑嗎?剛才還被質疑。不過,也沒跟他說了,反正他說他要行文到台灣大哥大去調閱申請那隻門號的資料,然後會再通知我。到時候再看著辦吧。
被當嫌疑犯的感覺真的很差耶,好像我講的每一句話都是騙人的,第一次被這種態度對待,唉!有些難受就是了。雖然終於知道的緣由,但我很不能認同的一件事就是為什麼像發生這種事,好像倒大楣的都是我們小老百姓,那些沒有確實的辨認身份,就讓對方辦了門號,難道他們沒有責任嗎?為啥只有我要被調查而沒有電信業者。
離開了警局後,總是要轉換個心情,爸、媽也難得來台中,於是我就硬拉著小書書和我爸媽一起走走,於是就選擇了離小書書家很近的梧棲漁港走走,這也是我待在台中那麼久,第一次去,其實也是可以預期啦,每個漁港其實都大同小異,不過媽還是買了少許的魚貨回去。本來是還打算去逢甲夜市走走順便吃晚餐的,後來想想逢甲夜市那停車有些困難,於是打消了這個念頭。後來我們是去沙鹿的一間貴族世家共進了晚餐。不過感覺這次的沙朗牛排不怎麼好吃,有點硬且咬不太下去。時間也愈來愈晚了,爸明天也還要上班,所以就先載我們回去牽機車,然後就驅車北上了,而我和小書書就往實驗室的方向回去。
最後,再次感覺所有幫住以及關心我的朋友們:小書書、阿佑、家祥、傑宇等實驗室所有的人。謝謝你們。還有,我最敬愛的爸和媽!
2007年11月15日 星期四
SYN flooding
對於任何一個listening socket,Kernel會維護兩個Queue:
- incomplete connection queue
- complete connection queue
其中incomplete connection queue是指Server收到Client SYN封包後,還沒完成Three-way handshaking的動作,反之,則會在complete connection queue裡。
由於Queue有一定的大小,所以攻擊者可以寫一個程式,用非常快的速率送出大量的SYN封包來填滿incomplete connection queue。除此之外,攻擊者往往也會偽造來源IP位址(IP spoofing),讓server無法得之攻擊者的實際位址。由於攻擊者用大量的SYN封包填滿imcomplete connection queue,所以會造成正常使用者無法連上此server,也是Denial of Service (DoS) 的一種。
標籤: Computer Network
Mobile IPv6環境重建
繞了一大圈,終於把Mobile IPv6的環境給弄回來,差點就完蛋了。
一開始測試時,還以為失敗了,怎麼移到新的子網路後,都沒有送Binding Update給Home Agent。原來是RADVD的問題,忘了設定RA發送時間的間隔。
接下來的工作就要想辦法將Mobile IPv6和SIP結合在一起了,主要就是要把Movement detection弄在一起,好像很困難的樣子。
2007年11月14日 星期三
2007年11月11日 星期日
Panic
糟糕,不知道該怎麼形容自己,我把我的Mobile IPv6的Mobile Node砍掉重灌,然後就架不起來了@@。
明明就按照之前記錄的步驟做,結果怎麼會這樣呢?
唉!本來已經很多事煩心了,現在又更煩了~~~
2007年11月8日 星期四
石破天驚的一擊
邁向第三年的亞洲職棒球大賽,由統一獅以及中國之星揭開序幕。
一局上,統一獅就得了一分,本想說應該又可以輕鬆取勝,沒想到比賽前半段卻打的如此艱辛。
中國棒球實力確實是在進步,不過距離台灣的水準應該還有一段距離,只不過,每次遇到中國隊總有那種不能輸的壓力,反而綁手綁腳。好在陳連宏那石破天驚的一擊,讓沉睡的獅子醒了。
不過,雖然不是統一獅的球迷,但看了今年的總冠軍賽,投手戰力實在是個隱憂。以前總覺得台灣的選手總是投優於打,現在卻反過來了。
2007年11月6日 星期二
IP位址轉換
如何將人讀的140.120.*.*的IP轉換成network byte order的兩進位表示,可以使用以下的函式(定義於"arpa/inet.h">:
// String to 32-bit binary
int inet_aton(const char *strptr, struct in_addr *addrptr);
// 32-bit binary to String
char *inet_ntoa(struct in_addr inaddr);
然而,以上的函式不能處理IPv6的問題,因此有另外兩個函式可以同時處理IPv4與IPv6:
int inet_pton(int family, const char *strptr, void *addrptr);
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
其中當處理IPv4時,family值為AF_INET,IPv6時則為AF_INET6。
inet_ntoa裡,size_t len為回傳string的長度,避免Overflow。
"netinet/in.h"有定義兩個常數,讓我們可以使用他來設定長度。
#define INET_ADDRSTRLEN 16 /* for IPv4 dotted-decimal */
#define INET6_ADDRSTRLEN 46 /* for IPv6 hex string */
2007年11月5日 星期一
回家渡假
一切都來的很突然,一早到實驗室拿了筆電就回台北了。也許是給自己太大的壓力,只有回到家才會回放鬆的感覺。
雖然說是回家渡假,但多少還是要有些進度。實驗或許不如預期,但論文還是要寫。已經說好下星期要交給老師修改過後的論文,所以,回家這幾天就來改一下論文,不會太累又可以休息。
話說明天過後,都是棒球比賽~~~
安裝NVIDIA顯示卡驅動程式
在Linux上安裝NVIDIA顯示下的驅動程式很容易,首先到官網下載適當的驅動程式。筆電顯卡為NVidia GeForce Go 7300,所以就載了NVIDIA-Linux-x86-100.14.19-pkg1.run。
安裝開始前,系統需具備一些編譯工具
# uname -r
2.6.22-2-686
# apt-get install linux-headers-2.6.22-2-686
# apt-get install build-essential
接著就可以開始安裝
# sh NVIDIA-Linux-x86-100.14.19-pkg1.run
按照指示一步一步做即可成功編譯。
Network Byte Order
Internet Protocols是採用Big-endian,因此有四個函式(定義於"netinet/in.h")可供我們轉換host byte order <--> network byte order:
uint16_t htons(uint16_t host16bitvalue) ; // host to network short
uint32_t htonl(uint32_t host32bitvalue) ; // host to network long
uint16_t ntohs(uint16_t net16bitvalue) ; // network to host short
uint32_t ntohl(uint32_t net32bitvalue) ; // network to host long
當處理port的時候,可以使用hotns()和ntohs()
當處理IPv4位址,可以使用hotnl()和ntohl()
2007年11月4日 星期日
Byte Odering
資料存在記憶體有兩種存法,一個為Big-endian,另一個為Little-endian。
- Big-endian:最高位元組(Significant Byte)存在記憶體的前頭。
- Little-endian:最低位元組(Least Significant Byte)存在記憶體前頭。
00000001 00000011 Big-endian
00000011 00000001 Little-endian
標籤: Computer Network
2007年11月3日 星期六
Value-Result
Socket address sturcture總是以reference(指標指向結構)傳進socket函式,而結構的大小也會被傳入。然而長度傳入的方法取決於process to kernel或是kernel to process。
Process to Kernel(bind, connect, sendto)
struct sockaddr_in serveraddr;
bind(sockfd, (Struct sockaddr *) &serveraddr, sizeof(serveraddr));
長度的資訊是用來告訴該copy多少資料從process到kernel
Kernel to Process(accept, recvfrom, getsockname, getpeername)
struct sockaddr_in clientaddr;
socklen_t letngth;
length = sizeof(clientaddr);
getpeername( sockfd, (Struct sockaddr*) &clientaddr, &length)
其中,長度的值會改變。用指標傳入,告訴kernel所傳入的struture大小。而當函式結束時,會回傳kernel儲存多少資料在structure,將值存在length上。像length這種參數稱為value-result參數。
2007年11月1日 星期四
Socket Address Structure
IPv4與IPv6的Socket Address Structure定義於"netinet/in.h"裡。
IPv4 Socket address structure: sockaddr_in
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr;
};
/* Structure describing an Internet socket address. */
struct sockaddr_in {
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8]; /* Padding */
};
/* IPv6 address */
IPv6 Socket address structure: sockaddr_in6
struct in6_addr {
uint8_t s6_addr[16];
};
struct sockaddr_in6 {
uint8_t sin6_len;
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port;
uint32_t sin6_flowinfo
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};