2013年5月9日 星期四

[C]結構內動態陣列大小設初值

參考:
http://stackoverflow.com/questions/1558025/c-initialize-array-within-structure

不是後來才用malloc的那種動態陣列。

typedef struct {
  int row;
  int col;
  char **ar;
}fooStruct;

static const foostruct fooArr[] = {
  {2, 10, (char*[2]) { (char[10]) {"hello"}, (char[10]) {"world"} } },
  .....
}

這樣宣告的話

fooArr[0].ar[0]就是hello
fooArr[0].ar[1]就是world

2013年5月7日 星期二

[Socket]server程式碰上TIME_WAIT的解法

參考:
http://stackoverflow.com/questions/587961/whats-the-difference-between-time-wait-assassination-and-so-reuseaddr
http://stackoverflow.com/questions/3229860/what-is-the-meaning-of-so-reuseaddr-setsockopt-option-linux

有時候server程式在需要重啟的時候,(像是重新讀設定檔)
會發現即使把程式結束,再開卻失敗的情況。

在這時候用netstat -al可以觀察到,server用的某些port正處於TIME_WAIT的情況,
並要持續一段時間才會自動消失(1~4分鐘都有可能)。
而在TIME_WAIT的這些port都是無法再利用,所以才會重啟失敗。

解決辦法就是在socket做bind之前,
做setsockopt的SO_REUSEADDR:

int i=1; 
setsockopt(iSock,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));

這樣的設定就是允許另一個socket bind在TIME_WAIT的port。
但是如果該port不是在TIME_WAIT而是其他使用中狀況,bind仍會失敗。

TIME_WAIT是TCP連線的正常狀態,
代表"可能還有未傳來的資料"。