遅くなりましたが、サンプルプログラムを作ってみました。
必ず、サーバーから先に起動してください。
サーバー側を起動させたまま、クライアントを立ち上げたり、終了してみたりしてサーバー側の表示を確認してください。
また、クライアントが3台以上起動できないことも確かめてみてください。
サーバー側のプログラム
#include "hspsock.as"
#const PORT_ST 1333
#define ctype PORT(%1) (PORT_ST + (%1)) ;指定されたIDのポートを返す
#const CONMAX 4
#const STATE_CLOSED 0 ;ソケットを開く前
#const STATE_OPENED 1 ;接続前
#const STATE_CONNECTED 2 ;接続中
dim constat_, CONMAX ;stat
repeat CONMAX
constat_(cnt) = STATE_CLOSED
loop
concnt_ = 0
;接続案内用(x1)と接続用(x3)にソケットを初期化
repeat CONMAX
sockmake cnt, PORT(cnt)
if( stat ): dialog "sockmake error. (code="+stat+")",1: goto *sock_error
constat_(cnt) = STATE_OPENED
loop
;接続待ち
title "接続待ち..."
*main
repeat CONMAX
switch constat_(cnt)
case STATE_OPENED
;接続待ち
sockwait cnt
if( stat > 1 ){
dialog "sockwait error. (code="+stat+", index="+cnt+")",1: goto *sock_error
}else:if( stat == 0 ){
;接続された
if( cnt == 0 ){
;接続案内
;利用可能なポート番号を探す
index = -1
repeat CONMAX-1,1 ;index=0は案内用に使っているので除く
if( constat_(cnt) == STATE_OPENED ): index=cnt: break
loop
msg=""
if( index == -1 ){
msg = "failed."
}else{
msg = ""+PORT(index)
}
sockput msg, 0
if( stat ): dialog "sockput error. (code="+stat+")",1: goto *sock_error
;接続案内用ソケットを再び接続待ち可能にする (切断→初期化)
sockclose 0
sockmake 0, PORT_ST
if( stat ): dialog "sockmake error. (code="+stat+")",1: goto *sock_error
}else{
;本接続
constat_(cnt) = STATE_CONNECTED
mes "system: port="+PORT(cnt)+" のソケットが接続されました"
concnt_++
title "接続中のソケット数="+concnt_
}
}
swbreak
case STATE_CONNECTED
;接続中
sockcheck cnt:ret=stat
if( stat == 2 ){
dialog "sockcheck error. (code="+stat+")",1: goto *sock_error
}else:if( stat == 0 ){
;データが到着
sdim buf, 64
sockget buf, 64, cnt
if( stat ){
;切断されてるっぽい
;切断
sockclose cnt
constat_(cnt) = STATE_CLOSED
mes "system: port="+PORT(cnt)+" のソケットが切断されました"
concnt_--
title "接続中のソケット数="+concnt_
;初期化
sockmake cnt, PORT(cnt)
if( stat ): dialog "sockmake error. (code="+stat+")",1: goto *sock_error
constat_(cnt) = STATE_OPENED
}else{
;受信データを処理
mes "port="+(PORT_ST+cnt)+" <"+buf+">received."
}
}
swbreak
swend
loop
await 0
goto *main
*sock_error
repeat CONMAX
if( constat_(cnt) != STATE_CLOSED ): sockclose cnt
loop
end
クライアント側のプログラム
#include "hspsock.as"
#define HOST "localhost"
#const INFORM_PORT 1333
port_ = 0
;接続案内用ポートに接続
sockopen 0, HOST, INFORM_PORT
if( stat ): dialog "sockopen error. (code="+stat+")",1: end
;データ受信待ち
title "ポート番号受信待ち..."
repeat
sockcheck 0
if( stat == 2 ): dialog "sockcheck error. (code="+stat+")",1: goto *sock_error
if( stat == 0 ): break
await 0
loop
;データを受信
sdim buf, 64
sockget buf, 64, 0
if( stat ): dialog "sockget error. (code="+stat+")",1: goto *sock_error
if( buf == "failed." ): dialog "server is busy.",1: goto *sock_error
port_ = int(buf)
;切断
sockclose 0
;本接続
sockopen 0, HOST, port_
if( stat ): dialog "sockopen error. (code="+stat+")",1: end
title "サーバー '"+HOST+"', ポート="+port_+" に接続しました。"
sdim msg_, 64
input msg_, 200, 20
button gosub "送信", *sock_sendmsg
*main
await 25
goto *main
*sock_sendmsg
sockput msg_, 0
if( stat ): dialog "sockput error. (code="+stat+")",1: goto *sock_error
return
*sock_error
sockclose 0
end