| Author |
Message |
< Erlang ~ cas...of with incoming binary |
| paolo |
Posted: Thu Jun 03, 2010 12:51 pm |
|
|
|
User
Joined: 03 Jun 2010
Posts: 11
|
Hi all!
i'm currently working on a cards game in erlang. The problem is the following:
i'm receiving the incoming commands through gen_tcp as:
Code:
receive
{tcp, Socket, Bin} ->
inet:setopts(Socket, [{active, once}]),
case Bin of
<<"join">> ->
.....
<<"get_cards">> ->
.....
<<"play", Number/integer, Seed/binary>> ->
.....
end,
i would like to receive also a "take" command, where user gives the card (only 1) he wants to play and a list of cards he want to take. I have no idea on how to put down the case option...any clues? The seed can be one among "denari", "bastoni", "coppe", "spade".
thanks in advance for your help!
paolo |
|
|
| Back to top |
|
| zajda |
Posted: Fri Jun 04, 2010 4:30 pm |
|
|
|
User
Joined: 22 Aug 2009
Posts: 83
|
I don't understand entirely what is the problem. Matching on a value which is a list? Why not add then an option with pattern <<"take", Somestuff/binary >> and cope with bounded variable later?
Since all you options have some 'constant' string at the beginning, there is no chance that incoming message will drop into wrong case clause. |
|
|
| Back to top |
|
| paolo |
Posted: Sat Jun 05, 2010 7:11 am |
|
|
|
User
Joined: 03 Jun 2010
Posts: 11
|
hi,
yes, you are right. The point is that can receive something as:
Code: <<"take", Number/integer, Seed/binary, OtherStuff/Binary>> ->
but OtherStuff may be for example [{7,denari}] or [{6,spade},{1,denari}] and so on...tbut i don't know ex ante the size of the list.
I was just thinking about a smart way to deal with this.
Paolo |
|
|
| Back to top |
|
| zajda |
Posted: Sat Jun 05, 2010 11:21 pm |
|
|
|
User
Joined: 22 Aug 2009
Posts: 83
|
| the last part of binary does not have to have declared length. Match on it and split it later. Be careful with building the binary - the good way is to collect all data and use binary_to_term. Binary_to_list can give you side effects. btw thats the easiest way.. maybe you should define some 'protocol' and parse defined offsets of bits. |
|
|
| Back to top |
|
| paolo |
Posted: Sun Jun 06, 2010 6:57 pm |
|
|
|
User
Joined: 03 Jun 2010
Posts: 11
|
| thanks, i will definitely follow your hints! |
|
|
| Back to top |
|
| zajda |
Posted: Tue Jun 08, 2010 9:19 am |
|
|
|
User
Joined: 22 Aug 2009
Posts: 83
|
| the 'match on last part' solution is kind of a hack. Now, I think that the nicest way (which is still simple) would be to send a message e.g. <<"take">> and it would be just a init-message and later send card by card. In this solutions you would have a gate (some Pattern) for single card, but initial message would set a state saying what this incoming card is doing. The other thing is tracking cards per player (to know which card comes from which user - executing particular part of the game). But this is just as simple: match on pid added at beginning. Btw it looks like FSM (finite state machine - take a look at gen_fsm) to manage state of the game. |
|
|
| Back to top |
|
| paolo |
Posted: Wed Jun 09, 2010 8:42 am |
|
|
|
User
Joined: 03 Jun 2010
Posts: 11
|
hi,
what about this?
1) user sends <<"take">>
2) user sends multiple times <<Number, Seed>> where the first one is the card he wants to play and the following are the card/s he wants to take
3) this cards are stored in the state of the gen_server
4) user sends <<"end-take">>
actually to know which player sent what i use the socket...
paolo |
|
|
| Back to top |
|
| zajda |
Posted: Wed Jun 09, 2010 4:30 pm |
|
|
|
User
Joined: 22 Aug 2009
Posts: 83
|
| yes, it looks good as far as you sort out the problem of injection to the state card send by malicious user. So, maybe also in state keep some tree structure which represents cards per socket/Pid/Id. |
|
|
| Back to top |
|
| paolo |
Posted: Thu Jun 10, 2010 6:51 am |
|
|
|
User
Joined: 03 Jun 2010
Posts: 11
|
yeah...i thought about that..
in my current implementation i'm storing in the state of the gen_server a list of sockets representing the players. every time a player does an action allowed by the game his socket goes to the end of the list (a sort of update_turn function).
thus in my case i did something like:
Code:
"get_cards" ->
case{is_player(Socket),is_player_turn(Socket)} of
{true, true} ->
.......
|
|
|
| Back to top |
|
|
|