|
 |
|
2013/3/19(Tue) 22:29:04|NO.53079
pcbnet2を使って、サーバとクライアントが通信して座標を共有するプログラムを作ったのですが
遅延が、なかなかひどいです。
どこを改善すればいいのでしょうか?
サーバ側プログラム
//Server
#include "pcbnet2.as"
//
port=1002
dfsock=0
usercnt=0
usersock=0
MAXCLIENT=10
putmessage=""
loopcnt=MAXCLIENT-1
dim sock,MAXCLIENT
sdim sockmsg,500,MAXCLIENT
//
tcpmake dfsock,port
if stat>0:mes "ポートがおかしいです。":stop
pos 250,250
input putmessage,360
button gosub "送信",*putmsg
*mainloop
repeat MAXCLIENT
title ""+cnt
if sock.cnt>0:tcpfail sock.cnt
if stat>0:sock.cnt=0:sockmsg.cnt=""
tcpwait dfsock
if stat=1{
gosub *newconnect
}
getmessage=""
if sock.cnt>0{
//tcpget getmessage,64,sock.cnt
tcprecv getmessage,0,35,sock.cnt
sockmsg.cnt = getmessage
}
loop
//gosub*getmsg
gosub*draw
gosub*putplayerinfo
goto*mainloop
*draw
redraw 0
syscolor 4
boxf
color
pos 0,0
repeat MAXCLIENT
if sock.cnt=0:status=status+"NUM"+cnt+":<DISCONNECT>\n"
if sock.cnt>0:status=status+"NUM"+cnt+":<CONNECT> 発言:"+sockmsg.cnt+"\n"
loop
mes status
redraw 1
status=""
return
*newconnect
//新しい接続要求が来たら
tcpaccept usersock,dfsock
repeat MAXCLIENT
//満員かチェック
if sock.cnt=0:break
if loopcnt=cnt{
result="満員"
tcpput result,usersock
tcpclose usersock
return
}
loop
repeat MAXCLIENT
if sock.cnt>0{
tcpiscon sock.cnt
if stat>1:sock.cnt = usersock:break
}else{
sock.cnt = usersock:break
}
mes stat
await 1
loop
result=""+MAXCLIENT
mes usersock+":"+stat
usersock2=str(usersock)
//tcpsend result,0,64,usersoc
tcpput result,usersock
return
*putmsg
repeat MAXCLIENT
if sock.cnt>0:tcpput putmessage,sock.cnt
await 1
loop
return
*getmsg
repeat MAXCLIENT
getmessage=""
if sock.cnt>0{
//tcpget getmessage,64,sock.cnt
tcprecv getmessage,0,64,sock.cnt
sockmsg.cnt = getmessage
}
loop
return
*putplayerinfo
sdim sendinfo,2048
repeat MAXCLIENT
sendinfo=sendinfo+sockmsg.cnt+"\n"
loop
repeat MAXCLIENT
if sock.cnt>0:tcpput sendinfo,sock.cnt
await 1
loop
return
クライアント側
//Client
#include "pcbnet2.as"
onexit*exit
/////////////////
port=1002
sock=0
ip="127.0.0.1"
message=""
putmessage=""
speed=1
charx=150
chary=150
//////////////////
screen 0,350,220
input ip,305
button "スタート",*start
stop
*start
screen 0,350,220
tcpopen sock,ip,port
if stat>0:mes "接続失敗":stop
title "接続中"
repeat
tcpget message,64,sock
MAXCLIENT=int(message)
if MAXCLIENT>0:break
tcpfail sock
if stat>0:goto*error
loop
dim psock,MAXCLIENT//プレイヤーの数だけ配列確保
dim rawuserinfox,MAXCLIENT
dim rawuserinfoy,MAXCLIENT
sdim psockmsg,500,MAXCLIENT//プレイヤーの数だけ情報確保
title "接続しました"
sdim getmessage,2048
*mainloop
repeat MAXCLIENT
tcpfail sock
if stat>0:goto*error
wait 1
///////////////////////////////////////////
getkey key,37
if key&1{
//左
if charx>0{
charx=charx-3
}
putmessage=""+charx+"&"+chary
tcpsend putmessage,0,35,sock
}
getkey key,38
if key&1{
//上
if chary>0{
chary=chary-3
}
putmessage=""+charx+"&"+chary
tcpsend putmessage,0,35,sock
}
getkey key,39
if key&1{
//右
if charx<ginfo_sizex-20{
charx=charx+3
}
putmessage=""+charx+"&"+chary
tcpsend putmessage,0,35,sock
}
getkey key,40
if key&1{
//下
if chary<ginfo_sizey-45{
chary=chary+3
}
putmessage=""+charx+"&"+chary
tcpsend putmessage,0,35,sock
}
tcprecv getmessage,0,2048,sock //他のプレイヤーの情報ゲット
notesel getmessage
repeat MAXCLIENT
noteget userinfo,cnt
if userinfo="":continue
px=strmid(userinfo,0,instr(userinfo,0,"&"))
py=strmid(userinfo,instr(userinfo,0,"&")+1,20)
px=int(px):py=int(py)
rawuserinfox.cnt=0: rawuserinfoy.cnt=0
rawuserinfox.cnt=px
rawuserinfoy.cnt=py
loop
redraw 0
syscolor 4:boxf:color:
pos charx,chary
mes "●"
repeat MAXCLIENT
pos rawuserinfox.cnt,rawuserinfoy.cnt
mes "■"
loop
title ""+cnt
redraw 1
wait 3
putmessage=""+charx+"&"+chary
tcpsend putmessage,0,35,sock
loop
goto *mainloop
*exit
end
*error
mes "接続が遮断されました"
stop
*getmsg
tcprecv getmessage,0,1024,sock.cnt
return

| |
|
2013/3/20(Wed) 09:36:38|NO.53089
repeat MAXCLIENTの部分が全体的にちょっとおかしい感じです。
ざっと見ただけですが かなり変更が必要だと思われます。
|
|
2013/3/20(Wed) 09:51:25|NO.53090
クライアント側
//Client.hsp
#include "pcbnet2.as"
//----------------------------------------//
// 初期設定
port=1002 // ポート番号
sock=0 // ソケットID
ip="127.0.0.1" // 接続先のipアドレス
message=""
putmessage=""
speed=3 // 速さ
charx=150 // 自分の座標x
chary=150 // y
//----------------------------------------//
screen 0,350,220
input ip,305
button "スタート",*start
stop
//----------------------------------------//
*start
clrobj
tcpopen sock,ip,port
if stat {
mes "接続失敗"
stop
}
title "接続中"
repeat
wait 1
tcpget message,64,sock
if stat {
MAXCLIENT=int(message)
if MAXCLIENT>0 {
break
}
}
tcpfail sock
if stat {
goto *error
}
loop
//----------------------------------------//
//プレイヤーの数だけ配列確保
dim rawuserinfox,MAXCLIENT // 座標x
dim rawuserinfoy,MAXCLIENT // 座標y
sdim psockmsg,500,MAXCLIENT // メッセージ
title "接続しました"
sdim getmessage,2048 // 受信したデータ
//----------------------------------------//
*mainloop
gosub *MoveCharacter // 自分を移動させる
gosub *Draw // キャラクターを描画する
gosub *RecvData // サーバと通信する
await 30
goto *mainloop
//----------------------------------------//
*MoveCharacter
// ウインドウがアクティブでなければ戻る
if ginfo(2) : return
// 自分を動かす
getkey key,37
if key{
//左
if charx>0{
charx -= speed
}
gosub *PutMyPos
}
getkey key,38
if key{
//上
if chary>0{
chary -= speed
}
gosub *PutMyPos
}
getkey key,39
if key{
//右
if charx<ginfo_sizex-20{
charx += speed
}
gosub *PutMyPos
}
getkey key,40
if key{
//下
if chary<ginfo_sizey-45{
chary += speed
}
gosub *PutMyPos
}
return
//----------------------------------------//
*Draw
// キャラクターを描画する
redraw 0
syscolor 4:boxf:color
pos charx,chary
// 自分
color 255
mes "●"
color 0,0,0
// 他のプレイヤー
repeat MAXCLIENT
if rawuserinfox.cnt = 0 & rawuserinfoy.cnt = 0 {
continue
}
pos rawuserinfox.cnt,rawuserinfoy.cnt
mes "■"
loop
redraw 1
return
//----------------------------------------//
*RecvData
// サーバとの通信が途切れていないかを確認する
tcpfail sock
if stat {
goto *error
}
// データを受信する
tcprecv getmessage,0,2048,sock //他のプレイヤーの情報ゲット(statに受信したバイト数が代入される)
if stat {
notesel getmessage
repeat MAXCLIENT
noteget userinfo,cnt
if userinfo="":continue
px=strmid(userinfo,0,instr(userinfo,0,"&"))
py=strmid(userinfo,instr(userinfo,0,"&")+1,20)
rawuserinfox.cnt=int(px)
rawuserinfoy.cnt=int(py)
loop
}
return
//----------------------------------------//
*PutMyPos
// 自分の座標をサーバへ送信
putmessage=""+charx+"&"+chary
tcpsend putmessage,0,35,sock
return
//----------------------------------------//
*error
color 255
pos 0,0
mes "接続が遮断されました"
stop
//----------------------------------------//

| |
|
2013/3/20(Wed) 10:08:44|NO.53091
サーバ側
//Server.hsp
#include "pcbnet2.as"
//----------------------------------------//
// 初期設定
port=1002 // 待機ポート番号
dfsock=0 // 待機ソケットID
usersock=0 // 一時的なソケットID
MAXCLIENT=10 // 最大のユーザー数
putmessage="" // 送信するメッセージ
loopcnt=MAXCLIENT-1
dim sock,MAXCLIENT
sdim sockmsg,512,MAXCLIENT
//----------------------------------------//
tcpmake dfsock,port
if stat {
mes "ポートがおかしいです。"
stop
}
pos 250,250
input putmessage,360
button gosub "送信",*putmsg_all
//----------------------------------------//
*mainloop
await 30
repeat MAXCLIENT
if sock.cnt = 0 {
// sockが0なら未接続なのでループを抜ける
continue
}
// 接続をチェック
tcpfail sock.cnt
if stat {
// 切断されていたらソケットを閉じる
tcpclose sock.cnt
sock.cnt=0
sockmsg.cnt=""
continue
}
// データを受信する
getmessage=""
tcprecv getmessage,0,35,sock.cnt
sockmsg.cnt = getmessage
loop
// 新しい接続をチェックする
tcpwait dfsock
if stat=1{
gosub *newconnect
}
gosub*draw
gosub*putplayerinfo
goto*mainloop
//----------------------------------------//
*draw
redraw 0
syscolor 4:boxf:color
pos 0,0
repeat MAXCLIENT
if sock.cnt {
status=status+"NUM"+cnt+" : <CONNECT> 発言:"+sockmsg.cnt+"\n"
}else {
status=status+"NUM"+cnt+" : <DISCONNECT>\n"
}
loop
mes status
status=""
redraw 1
return
//----------------------------------------//
*newconnect
//新しい接続要求が来たら
tcpaccept usersock,dfsock
repeat MAXCLIENT
//満員かチェック
if sock.cnt=0 {
// 空きがあったのでそこに代入
sock.cnt = usersock
break
}
if loopcnt=cnt {
// *ここはクライアント側に該当する処理がないので無意味
result="満員"
tcpput result,usersock
tcpclose usersock
return
}
loop
// ユーザー数をクライアントへ送信
result=""+MAXCLIENT
tcpput result,usersock
return
//----------------------------------------//
*putmsg_all
// 接続しているすべてのクライアントに送信
repeat MAXCLIENT
if sock.cnt {
tcpput putmessage,sock.cnt
}
loop
return
//----------------------------------------//
*putplayerinfo
// 送信するデータを作成
sdim sendinfo,2048
repeat MAXCLIENT
sendinfo=sendinfo+sockmsg.cnt+"\n"
loop
// 接続しているすべてのクライアントに送信
repeat MAXCLIENT
if sock.cnt {
tcpput sendinfo,sock.cnt
}
loop
return
# LANの内部ではこれでも正常に動作しますが、外からアクセスすると多分動きません。

| |
|
2013/3/20(Wed) 20:14:11|NO.53105
やはり、その程度にはなってしまうのですね。
もうちょっと、別な方法を考えてみます。
ありがとうございました。
|
|