老地方冰果室交流區

歡迎冰果室讀者在此交流
現在的時間是 11/21/2019 2:26 pm

所有顯示的時間為 UTC + 8 小時




發表新文章 回覆主題  [ 19 篇文章 ] 
發表人 內容
 文章主題 : 無法 listen port?
文章發表於 : 10/28/2004 11:32 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
我為了測試網路通訊協定,寫了一個 listen TCP port 的程式,動作很簡單,就只是把接收到的東西印在螢幕上。雖說是寫,其實是從 Wrox 那本 Programming Linux 抄下來的,code 如下:

代碼:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define SERVER_IP   "192.168.1.200"
#define SERVER_PORT   9876

int main(void) {

   int bytes;
   int server_fd,  client_fd;
   int server_len, client_len;
   struct sockaddr_in server_addr;
   struct sockaddr_in client_addr;
   char buffer[255];

   server_fd = socket(AF_INET, SOCK_STREAM, 0);
   if(server_fd<0) {
      perror("Can not create Socket");
      _exit(1);
   }
   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons(SERVER_PORT);
   inet_aton(SERVER_IP,&server_addr.sin_addr);
   bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
   listen(server_fd, 5);
   while(1) {
      printf("server ready\n");
      client_len = sizeof(client_addr);
      client_fd = accept(server_fd,
         (struct sockaddr *)&client_addr, &client_len);
      while((bytes=read(client_fd, buffer, 255))>0) {
         buffer[bytes]=(char)NULL;
         printf(buffer);
      }
      close(client_fd);
   }
   _exit(0);
}


放在 OS X 上用 gcc 編譯、執行都無問題,但是 client 端卻一直無法建立連線。我到 Share 下檢查過防火牆設定,沒有開啟。檢查過網路,可以排除所有 IP 設定錯誤、網路連線不通等等雜七雜八的失誤。後來我把整段程式搬到 Linux 機器上,編譯執行,用同一個 client 端連,卻可以成功建立連線。

請問為什麼會這樣呢?我確定 OS X 可以用 Socket 的方式建立網路連線,我使用同樣來源的 Client 端程式在 Mac 上跑,連到 Linux Server,就可以動作。難道 OS X 的 Socket Listen 都要經過系統 API 登記之後才允許開放?
搞不懂...

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 : Re: 無法 listen port?
文章發表於 : 10/29/2004 12:28 am 
離線
討論區管理員
頭像

註冊時間: 05/02/2001 1:01 am
文章: 1297
ulysses 寫:
放在 OS X 上用 gcc 編譯、執行都無問題,但是 client 端卻一直無法建立連線。我到 Share 下檢查過防火牆設定,沒有開啟。檢查過網路,可以排除所有 IP 設定錯誤、網路連線不通等等雜七雜八的失誤。後來我把整段程式搬到 Linux 機器上,編譯執行,用同一個 client 端連,卻可以成功建立連線。


你這隻在 PowerMac G4 Cube/Mac OS X 10.3.5/gcc 3.3-20030304-apple_build1666 下跑很正常。

你要不要抓回去試看看?

_________________
[digdog dig];


最後由 digdog 於 10/29/2004 12:34 am 編輯,總共編輯了 1 次。

回頂端
 個人資料  
 
 文章主題 : Re: 無法 listen port?
文章發表於 : 10/29/2004 12:32 am 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
digdog 寫:
你這隻在 PowerMac G4 Cube/Mac OS X 10.3.5/gcc 3.3-20030304-apple_build1666 下跑很正常。


:shock: :x :evil: :cry: (無言...)

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 : Re: 無法 listen port?
文章發表於 : 10/30/2004 10:42 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
digdog 寫:
你這隻在 PowerMac G4 Cube/Mac OS X 10.3.5/gcc 3.3-20030304-apple_build1666 下跑很正常。
你要不要抓回去試看看?


我的 gcc 環境和你是一樣的。
經過多次測試,我決定這是 GCC 的問題。怎麼說呢,

原本第 20 行是這樣:

代碼:
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buffer[255];


改成這樣就不行:
代碼:
char buffer[255];
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;


更誇張的,改成這樣也不行
代碼:
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buffer[255];
int wxyz;


我認為是 gcc 分配記憶空間出了鎚,要不就是 OS X 內部有什麼鬼,讓同一隻程式的執行結果都不相同。

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 11:24 am 
離線
留言破百
頭像

註冊時間: 12/22/2003 5:49 pm
文章: 105
那如果改成 char buffer[256]; or char buffer[300] 呢?
另外,while(1) 無限迴圈不是好的寫法.....

請問你的 GCC 是哪個版本?是這個嗎?

— Mac OS X 10.2.6 or later
— Developer tools with the update of GCC to 3.3

我在 Apple 找不到 download GCC 3.3 的地方....


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 1:46 pm 
離線
嗜冰客
頭像

註冊時間: 04/30/2001 1:01 am
文章: 1048
來自: Metropolis Asylum
個人認為用 while(1) 沒有什麼問題,得多時用 break 是比較好用和簡單。況且 while(1) /for(::) 等寫法,幾乎每一個程式也有使用,非常 common。

_________________
圖檔
It is not god who created man. It is man who created God.

Light travels faster than sound. This is why some people appear bright until you hear them speak.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 2:03 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
brent 寫:
那如果改成 char buffer[256]; or char buffer[300] 呢?


應該說,我完全搞不清楚到底出了啥問題。以上說的已經進入工程師的巫醫療法範疇 :twisted:

順便一提,buffer 大小的界限是在 450~480 左右 :twisted:

brent 寫:
另外,while(1) 無限迴圈不是好的寫法.....


全看你在什麼環境下開發程式。非多作業環境,像 OS 9,用 while(1) 會出鎚。而在純多工作業環境中,這只是要一個程序(Process)重複執行裡面的工作而已。

上面的無限迴圈中一開始就會碰到 accept 這個 blocking 形態的 function 呼叫,程式就會進入等待狀態,不會一直耗用 CPU 時間。

要結束陷入無限循環的程式,有幾種方法:

1. 不理它,等它自己 core dump :twisted: :twisted: :twisted: 我曾經在 SunOS 上測試過失控的遞迴呼叫,如果有 pass value,大概遞迴到第一千多層就爆了。沒有 pass value 的話,大概可以跑到一萬多層。

2. 送個會停止執行的訊號給它,使用 kill 指令。溫和一點就 kill -SIGINT 或 kill -SIGTERM,有些程式會加上 TERM 的 Signal handler 作一些垃圾清除動作再退出,暴力一點就直接 kill -9 送強制終止訊號出去。

引言回覆:
請問你的 GCC 是哪個版本?是這個嗎?
— Mac OS X 10.2.6 or later
— Developer tools with the update of GCC to 3.3
我在 Apple 找不到 download GCC 3.3 的地方....


我用的是 Xcode 1.5 裝的版本。

Anyway,我已經放棄自己寫 listen port 了,改用 Port Test。RB 弄的 Carbon 程式,難看一點沒關係可以用就好。

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 2:20 pm 
離線
嗜冰客
頭像

註冊時間: 04/30/2001 1:01 am
文章: 1048
來自: Metropolis Asylum
ulysses 寫:
brent 寫:
另外,while(1) 無限迴圈不是好的寫法.....


全看你在什麼環境下開發程式。非多作業環境,像 OS 9,用 while(1) 會出鎚。而在純多工作業環境中,這只是要一個程序(Process)重複執行裡面的工作而已。


用什麼 flow control,同 OS 無關係吧? :roll:

難度 OS 9 中就不能在 while loop 中置入 WaitNextEvent() 了嗎? :x

反而真正的問題在於以上程式沒有辦法 exit 個 infinitely loop! :evil:


_________________
圖檔
It is not god who created man. It is man who created God.

Light travels faster than sound. This is why some people appear bright until you hear them speak.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 3:45 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
janusng 寫:
用什麼 flow control,同 OS 無關係吧? :roll:
難度 OS 9 中就不能在 while loop 中置入 WaitNextEvent() 了嗎? :x
反而真正的問題在於以上程式沒有辦法 exit 個 infinitely loop! :evil:
說?,倒是離題越來越遠。 :oops:


以上程式的 while(1) 目的很單純就是不要程式結束,如果 while loop 中沒有加上讓程式執行擱置的呼叫例如 sigsuspend、sleep 或是 accepe、open 之類,在單工作業的 OS 下就有可能把所有工作排程通通佔掉。如果是在 OS9 時代用 CodeWarrior,我絕對不敢這樣寫。這樣寫的話,就可能會變成要按下 cmd+option+esc 進入 interrupt 狀態才能跳出來。而在 UNIX 上,有時候我會不小心把一個 read() 弄成 Nonblock 狀態,讓程式從同步等候變成循序掃描,而在使用時一點差異都沒有。

再說 WaitNextEvent,雖然說 sigsuspend 也是讓程序等待下一個 Signal 進來,但是 Signal 本身是以“Interrupt”的方式在執行,除非有用 signal mask 把一個訊號 pending 掉,否則 Signal 與 WaitNextEvent 的執行流程完全不同。在 WaitNextEvet 的架構下流程是這樣:

1. 程式正在忙著做 I/O 和計算
2. 有 Event 進來了
3. 程式沒有立刻處理,Event 先堆在 Queue 中
4. 程式還在忙著做 I/O 和計算...
5. 同上.
6. 同上..
7. ...
.
.
.
N. 終於做完了
N+1. 回到 WaitNextEvent,把冰凍了好久的 Event 從 Queue 裡面拿出來...

而 UNIX Signal 則是:

1. 程式正在忙著做 I/O 和計算
2. 有 Signal 進來了
3. 程式正在進行的 I/O 與計算立刻擱置,不管你現在在哪一行,都通通進去 Interrupt 處理程序
4. Interrupt 處理程序完成,回去處理剛剛的工作

單工與多工系統在 Flow control 上最大的不同,就是在這個 Multiple Inter-Process Communication 上。多工系統的同步作業是個非常難處裡的問題。


【回到正題】

我在上面的程式碰到的最大問題就是我找不到成敗的規律。有時候前一種寫法可以,加上完全無關的一兩行程式碼重新編譯執行,就不行了。把那一兩行程式刪掉再重新編譯,又可以了。我還是認為是 GCC 的問題。

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 3:49 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
繼續用巫醫療法測試:最後終於發現,只要把 struct sockaddr_in server_addr 的宣告放在 main 外面變成 global,就不會有問題。果然還是 gcc 的問題。

無論如何謝謝各位的幫忙,把完整原始碼(包含參數設定、signal 處理)PO 在下面:

代碼:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define DEFAULT_SERVER_IP   "127.0.0.1"
#define DEFAULT_SERVER_PORT   9876

struct   sockaddr_in server_addr;
int      server_fd = 0;

void terminate(int sig) {
   if(server_fd>0) {
      close(server_fd);
      puts("[socket closed]");
   }
   _exit(0);
}

int main(int argc, char **argv) {

   int      bytes, opt, use_default=0;
   int      my_port = 0;
   int      client_fd;

   struct sigaction   sigreg;

   char   my_ip[20];
   char   buffer[255];

   bzero(buffer,sizeof(buffer));
   bzero(my_ip,sizeof(my_ip));

   if(argc>1) {
      while ((opt=getopt(argc,argv,"i:p:t:b:d"))!=-1)
      {
         switch (opt)
         {
            case 'i':
               strcpy(my_ip,optarg);
               break;
            case 'p':
               my_port = atoi(optarg);
               break;
            case 'd':
               use_default = 1;
               break;
            default :
               printf("usage: listen -i [ip] -p [port]\n");
               _exit(0);
         }
      }
   }

   if(use_default) {
      if(strlen(my_ip)<=0){
         strcpy(my_ip,DEFAULT_SERVER_IP);
      }
      if(my_port<=0){
         my_port = DEFAULT_SERVER_PORT;
      }
   }
   if( my_port<=0 || strlen(my_ip)<=0   ) {
      printf("usage: listen -i [ip] -p [port]\n");
      exit(0);
   }

/*  register signal handler */

   sigreg.sa_handler = terminate;
   sigreg.sa_flags = 0;
   sigemptyset(&sigreg.sa_mask);
   sigaddset(&sigreg.sa_mask,SIGTERM);
   sigaddset(&sigreg.sa_mask,SIGHUP);
   sigaddset(&sigreg.sa_mask,SIGALRM);
   sigaddset(&sigreg.sa_mask,SIGPIPE);
   sigaddset(&sigreg.sa_mask,SIGUSR1);
   sigaddset(&sigreg.sa_mask,SIGUSR2);
   sigaction(SIGINT, &sigreg, 0);

   sigemptyset(&sigreg.sa_mask);
   sigaddset(&sigreg.sa_mask,SIGINT);
   sigaddset(&sigreg.sa_mask,SIGHUP);
   sigaddset(&sigreg.sa_mask,SIGALRM);
   sigaddset(&sigreg.sa_mask,SIGPIPE);
   sigaddset(&sigreg.sa_mask,SIGUSR1);
   sigaddset(&sigreg.sa_mask,SIGUSR2);
   sigaction(SIGTERM, &sigreg, 0);

/*   Name the socket.  */

   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons(my_port);
   if(inet_aton(my_ip,&(server_addr.sin_addr))==0) {
      fprintf(stderr,"invalid address: %s [%s]\n",
         my_ip,strerror(errno));
      exit(-1);
   }

/*   Create an unnamed socket for the server.  */

   server_fd = socket(AF_INET, SOCK_STREAM, 0);
   if(server_fd<0) {
      perror("can not create socket");
      _exit(1);
   }

   if(bind( server_fd,
          (struct sockaddr *)&server_addr,
          sizeof(server_addr) ) == -1 ) {
      fprintf(stderr,"error when bind to %s:%d (%08x)\n[%d]: %s\n",
         my_ip,my_port,server_addr.sin_addr,errno,strerror(errno));
      exit(-1);
   }

/*   Create a connection queue and wait for clients.    */

   if(listen(server_fd, 5)==-1) {
      perror("error when listen port\n");
      exit(-1);
   }
   while(1) {

      printf("[%s:%d] standby\n",my_ip,my_port);

/*   Accept a connection.  */

      client_fd = accept(server_fd,(struct sockaddr *)NULL,(int *)NULL);
      if(client_fd<=0) {
         perror("error when accept connection");
         exit(-1);
      }

/*   We can now read/write to client on client_fd.  */

      while((bytes=read(client_fd, buffer, 255))>0) {
         buffer[bytes]=(char)NULL;
         printf(buffer);
      }
      close(client_fd);
      
      printf("[%s:%d] socket closed\n",my_ip,my_port);
   }
   _exit(0);
}

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 5:57 pm 
離線
嗜冰客
頭像

註冊時間: 04/30/2001 1:01 am
文章: 1048
來自: Metropolis Asylum
ulysses 寫:
在 WaitNextEvet 的架構下流程是這樣:

1. 程式正在忙著做 I/O 和計算
2. 有 Event 進來了
3. 程式沒有立刻處理,Event 先堆在 Queue 中
4. 程式還在忙著做 I/O 和計算...
5. 同上.
6. 同上..
7. ...
.
.
.
N. 終於做完了
N+1. 回到 WaitNextEvent,把冰凍了好久的 Event 從 Queue 裡面拿出來...

而 UNIX Signal 則是:

1. 程式正在忙著做 I/O 和計算
2. 有 Signal 進來了
3. 程式正在進行的 I/O 與計算立刻擱置,不管你現在在哪一行,都通通進去 Interrupt 處理程序
4. Interrupt 處理程序完成,回去處理剛剛的工作

單工與多工系統在 Flow control 上最大的不同,就是在這個 Multiple Inter-Process Communication 上。多工系統的同步作業是個非常難處裡的問題。


這個也和 while(1) 無關係,請問在 OS 9之下,你用什麼辦法可以不用等到N. 終於做完了,便回應的?不論用不用 while(1) ,恐怕也是不可能吧?這個是 OS 問題,和 while(1) 無關。

_________________
圖檔
It is not god who created man. It is man who created God.

Light travels faster than sound. This is why some people appear bright until you hear them speak.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 11:35 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
janusng 寫:
這個也和 while(1) 無關係,請問在 OS 9之下,你用什麼辦法可以不用等到N. 終於做完了,便回應的?不論用不用 while(1) ,恐怕也是不可能吧?


在單工作業環境下,的確會有你說的狀況發生。但是要讓它不用等到 “終於做完了” 才回應,還是有辦法做到的:使用 multi-thread 來分別執行計算、監督與界面。這種做法我曾經用過,確定它管用。當然這樣做效率不是很好看。

janusng 寫:
這個是 OS 問題,和 while(1) 無關。


離題越來越遠了。回到這個話題最早的起源:

ulysses 寫:
brent 寫:
另外,while(1) 無限迴圈不是好的寫法.....
全看你在什麼環境下開發程式。


while(1),說到底,它只是一種流程控制技巧而已,就好像 if、for,以及 goto。每個人有不同的認定與寫作習慣,只要你的程式碼能夠 work,就無所謂好壞。不管黑貓白貓,會抓老鼠的就是好貓。

但是當問說 while(1) 放在程式中適不適當,我會回答:這應該要看使用的時機與地點。怎麼說呢?舉個例子,你要去跟女朋友約會時,會送她一束菊花嗎?你要去參加葬禮,你會送往生者家屬一束紅玫瑰嗎?菊花和玫瑰花本身沒有錯,但是要看時間和地點。

以我上面的程式為例:

1. 如果這是給 OS9 用的程式,我會說『這樣做不恰當,應該要把無限迴圈放在另一個 thread 中,以免把系統鎖死。』

2. 如果這是給 UNIX 用的程式,我會說『OK,這樣做適合作為一個 daemon 或是背景執行的伺服器程式,只是 Log 與 Signal 處理應該要再完整些。』

同樣的 while(1) 在不同的作業環境下,就應該有不同的適用時機與適用地點。這是因為在不同的作業環境中,同一段 while 控制程式碼未必會有同樣的執行路徑與反應。所以,while(1) 不是好不好的問題,而是使用的時機與地點適不適當、系統環境與程式結構能不能符合需求的問題。


退後一步,不要用這麼嚴肅的程式分析方式來看這件事,單就從很單純的『一個工程師在寫程式的時候會怎麼做』來想:他寫一段程式碼,一定會要測試測試。那麼他在 OS9 上執行和在 OS X 上執行,就會有不同的結果:

a. 在 OS9 下,如果中斷點旗標沒有處理好(這是很可能的),又沒有用 thread 等程式技巧(通常不會),while(1) 可能會搞到必須強制關機。

b. 在 OS X 下就不必想這麼多,記憶體保護讓程式不可能抓狂到把系統搞砸,系統中斷支援讓沒有中斷點旗標的 while(1) 迴圈可以隨時終止。

因此,我在寫程式的時候:

i. 在 OS9 下就不喜歡用 while(1) 來控制,因為在程式開發的時候難免出鎚,一旦一個 break 的條件沒有弄對,結果就很難看。所以我能免則免。

ii. 在 OS X 下我就沒有那麼多顧慮,開兩個 terminal 一個跑程式一個跑 ps + kill,while(1) 可以就用的很高興。

也就是說,當我在思考 flow control 的方式時,不同的作業環境特性影響我的決定。

這是主觀的寫作風格問題。每個人寫作有不同的習慣有不同的風格,我寫程式寫了幾十年,這是我的寫作習慣。你可以不同意我的論點,但是我養成這種習慣自有我自己的道理。

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 10/31/2004 11:43 pm 
離線
討論區管理員
頭像

註冊時間: 05/02/2001 1:01 am
文章: 1297
哇,這是數週來看到最精彩的討論,拍拍手~ :D

受益良多,受益良多。

--
請原諒我的私心將此討論置頂讓人看個夠~

_________________
[digdog dig];


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 11/01/2004 8:19 am 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
可是到最後我的問題還是沒有解決 :oops: :oops: :oops:
把一個變數從 local 搬到 global,這是巫醫療法... :oops: :oops: :oops:
我看我還是去向 AppleDev 部門的人反應反應好了

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 11/01/2004 12:02 pm 
離線
嗜冰客
頭像

註冊時間: 04/30/2001 1:01 am
文章: 1048
來自: Metropolis Asylum
小弟終於認真的測試了那個 sample 程式。

在 XCode 1.5 使用 System version 3.3: gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1666) 來 Compile 試試。不論是
代碼:
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buffer[255];

還是
代碼:
char buffer[255];
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;

或是
代碼:
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buffer[255];
int wxyz;

還有
代碼:
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buffer[300];

都沒有問題。

再到 Terminal 試過 gcc (3.3) 也一樣行。

看來是閣下的 developer Tools 有問題居多。不如先試試 reinstall Developer Tools。

_________________
圖檔
It is not god who created man. It is man who created God.

Light travels faster than sound. This is why some people appear bright until you hear them speak.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 11/01/2004 12:16 pm 
離線
嗜冰客
頭像

註冊時間: 04/30/2001 1:01 am
文章: 1048
來自: Metropolis Asylum
[off topic]

有關 while(1) 的問題:
引言回覆:
1. 如果這是給 OS9 用的程式,我會說『這樣做不恰當,應該要把無限迴圈放在另一個 thread 中,以免把系統鎖死。』

這個還是和 while(1) 沒有關係!在你新開的 thread 中,還不是一樣有 while(1)?
引言回覆:
i. 在 OS9 下就不喜歡用 while(1) 來控制,因為在程式開發的時候難免出鎚,一旦一個 break 的條件沒有弄對,結果就很難看。所以我能免則免。

難道將 break 的 condition (a),搬到 while (!a) 便可以保證不出鎚?要是 a 永不 true 或是 while 永不會行第二次的話,怎樣寫也是會 infinite loop 的。 while(1) 或 while(!a) 也沒有不同!

小弟當然也痛恨不少人的壞習慣,或不明就裏的胡亂寫。但問題明顯不在 while(1) 上。

_________________
圖檔
It is not god who created man. It is man who created God.

Light travels faster than sound. This is why some people appear bright until you hear them speak.


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 11/01/2004 1:48 pm 
離線
討論區管理員
頭像

註冊時間: 05/18/2001 1:01 am
文章: 2475
來自: Forgotten Realm
janusng 寫:
看來是閣下的 developer Tools 有問題居多。不如先試試 reinstall Developer Tools。


我有兩台機器,環境都是 10.3.5,安裝 Xcode 1.5,兩台機器都有相同的狀況。當然我在理智上認為問題應該不是出在 address_in 變數怎麼宣告這種不科學的問題。

我試著把所有的 function call 用 errno 檢查,結果問題都是出在 bind:“The specified address is not available from the local machine”。檢查 server_addr.sin_addr 的值始終都是同樣的數值。

所以我是在懷疑,是不是 socket bind 要透過 darwin 底層建立連接的時候,有什麼機制在跟我的 process 搶控制權。

janusng 寫:
off topic


off topic 的部份我不再回應了,完全是在雞同鴨講,再扯下去就要翻臉了。

_________________
ash nazg durbatuluk, ash nazg gimbatul,
ash nazg thrakatuluk agh burzum-ishi krimpatul.


最後由 ulysses 於 11/01/2004 5:14 pm 編輯,總共編輯了 2 次。

回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 11/01/2004 3:48 pm 
離線
留言破百
頭像

註冊時間: 12/22/2003 5:49 pm
文章: 105
引言回覆:
回到這個話題最早的起源:
ulysses 寫到:
brent 寫到:
另外,while(1) 無限迴圈不是好的寫法.....
全看你在什麼環境下開發程式。


好像變成在吵這個了~

我完全認同 ulysses 的看法,我也只是說【 無限迴圈不是好的寫法.....】並不是絕對不能用,特別是這種測試用的小程式,只要能 work,管你喜歡 for 無限還是 while 無限....

只不過在大型程式中還是少用的好,以免 exit 的情況萬一沒發生時,就..... 要是【無限迴圈】用太多,也增加除錯的困難。這點你也知道,當我沒說.....

當然,寫了 while(條件) 也不等於就一定不會造成【無限迴圈】,萬一設定的條件沒發生,還不是一樣!

我有空也裝一下 Xcode 1.5 來跑看看好了。


回頂端
 個人資料  
 
 文章主題 :
文章發表於 : 11/01/2004 4:55 pm 
離線
嗜冰客
頭像

註冊時間: 04/30/2001 1:01 am
文章: 1048
來自: Metropolis Asylum
都是不用吵了,兩位大大是否可以為這個程式,示範一個不會有 while(1) 、while(!a) 或 equivalent(如 for(:: )、do ... while(1))的弊病,而又保留原有功能的寫法呢?

多謝賜教! :D

_________________
圖檔
It is not god who created man. It is man who created God.

Light travels faster than sound. This is why some people appear bright until you hear them speak.


回頂端
 個人資料  
 
顯示文章 :  排序  
發表新文章 回覆主題  [ 19 篇文章 ] 

所有顯示的時間為 UTC + 8 小時


不能 在這個版面發表主題
不能 在這個版面回覆主題
不能 在這個版面編輯您的文章
不能 在這個版面刪除您的文章
不能 在這個版面上傳附加檔案

搜尋:
前往 :  
POWERED_BY
正體中文語系由 竹貓星球 維護製作