C# - 客户端1从服务器接收的数据与客户端2发送的数据不同

时间:2016-04-17 16:05:44

标签: c# sockets client-server

我有一个问题,我的同事都不愿意帮助我所以我问他是否可以帮助我 -

我有一个关于c#表单的项目来创建一个客户端(讲师给了我们服务器的python代码 - 只是将数据从播放器传递给播放器),它将与另一个客户端(播放器)进行一场卡片游戏。 / p>

玩家点击一张卡片,然后随机选择一张卡片并以特定协议将其发送到服务器。 来自第一个点击该卡的玩家的第一条消息被发送并收到。

第二位玩家点击一张牌后显示问题 -  他将数据发送到服务器,但第二个播放器接收零字节数组 - 0000。

我一直在寻找答案,但没有找到,我真的很绝望。有人可以帮帮我吗。

我写的客户代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Resources;
using System.Drawing;
using System.IO;
using System.Reflection;

using System.Threading;


namespace HW6_GuyYoffe
{
    public partial class Form1 : Form
    {

        //connection
        bool connected, connectionSucceed = false;
        TcpClient client;
        NetworkStream clientStream;
        byte[] buffer = new byte[MSG_SIZE];
        IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), PORT_NUMBER);
        //game
        public int ansFromUser = 0;
        string oppCard, userCard;
        int userScore = 0, oppScore = 0;
        bool cardChosen;
        readonly object key = new object();


        public Form1()
        {
            //creates the form
        }

        //generate card images on the screen
        private void GenerateCards(int numOfCards, int startX, int startY)
        {
            //creates the cards on the screen 
        }

        // called when user clicks a card
        private void ClickOnCard(System.Windows.Forms.PictureBox currentPic)
        {    

            //code...
            buffer = new ASCIIEncoding().GetBytes("1" + userCard); //usercard - the random card of the current user

            clientStream.Write(buffer, 0, buffer.Length);//send to server the chosen card
            clientStream.Flush(); 
            Array.Clear(buffer, 0, buffer.Length);
            lock (key)
            {
                cardChosen = true;
                Monitor.Pulse(key);
            }
        }


        //called when form is created
        public void PlayGame(object sender, EventArgs e)
        {
            client = new TcpClient();
            ansFromUser = OK;
            StartThread();
        }

        //main function
        private void TalkToServer(IPEndPoint serverEndPoint)
        {
            if (ansFromUser != CLOSE_PROGRAM)
            {
                if (!connected)
                    ConnectToServer(serverEndPoint); //connect to server - pretty obvious 
                if (ansFromUser == CLOSE_PROGRAM)
                {
                    BeginInvoke((MethodInvoker)delegate { this.Dispose(); });

                    return;
                }

                do
                {
                    int bytesRead = 0;
                    try
                    {
                        Array.Clear(buffer, 0, buffer.Length);
                        bytesRead = clientStream.Read(buffer, 0, 4); //waits for 4 bytes from server

                        //// HERE is the problem - in the second time a clients sends his pick the buffer is 0000 - [0,0,0,0]
                    }
                    catch (Exception err3)
                    {
                        ///error
                    }
                    if (bytesRead > 0)
                    {
                        string input = new ASCIIEncoding().GetString(buffer); //converts byte array to string
                        if (!connected)
                        {
                            if (input == "0000") //start game message
                            {
                                //starts game
                            }
                            else
                            {
                                //error
                            }
                        }
                        else
                        {
                            if (input == "2000") //end game message
                            {
                                ansFromUser = CLOSE_PROGRAM;
                                this.Dispose();
                            }
                            else if (input[0] == '1')//recieving the opponent's card
                            {
                                oppCard = input.Substring(1); //without the message type
                                int result = OpponentCard();
                                userScore += result;
                                oppScore -= result;
                            }
                            else
                            {
                                //error
                            }

                    }                      
                    else
                    {
                        ///error
                        break;
                    }

                    }

                    Array.Clear(buffer, 0, buffer.Length);

                } while (ansFromUser == OK); //while answer isn't end 
            }





        }


        //uses another form. Shows the error that have occurred and asks the user if he wants to try again. If so - tries again
        private void ErrorMsgBox(string errorDetails)
        {
            ErrorBox errMsgBox = new ErrorBox(this, errorDetails);
            errMsgBox.ShowDialog();
        }

        private void ConnectToServer(IPEndPoint serverEndPoint)
        {
            // connect to server
        }

        private int OpponentCard()
        {
            const int WIN = 1;
            const int TIE = 0;
            const int LOOSE = -1;
            int result;

            lock (key)
            {
                while (!cardChosen) //wait until opponent and user chose cards
                    Monitor.Wait(key);
                Monitor.Pulse(key); //card is chosen
                cardChosen = false; //reset
            }



            int oppCardNum = int.Parse(oppCard.Substring(0, 2));
            int userCardNum = int.Parse(userCard.Substring(0, 2));
//...

            result = oppCardNum < userCardNum ? WIN : (oppCardNum == userCardNum ? TIE : LOOSE); //returns the result

            return result;

        }                

        private void StartThread()
        {
            if (ansFromUser != CLOSE_PROGRAM)
            {
                Thread serverStart = new Thread(() => TalkToServer(serverEndPoint)); //passing the thread the parameters
                serverStart.Start();
            }



        }
    }
}

如果有人想看 - python服务器代码 -

import socket
import select
import Queue

PORT = 8820
HOST = '127.0.0.1'

server = socket.socket()
server.setblocking(0)
server.bind((HOST,PORT))
client = []

while True:
    print "new game loop"
    clients_connected = 0
    server.listen(2)

    #Sockets from which we expect to read or write to
    inputs = [server]

    #waiting for both the connextion to be established
    while clients_connected < 2:
        readable, writeable, exceptional = select.select(inputs,inputs,inputs)
        #handle inputs
        for s in readable:
            if s is server:
            #A readable server socket is ready to accept a connection
                conn, addr = s.accept()
                print "one connection has been established"
                conn.setblocking(0)
                inputs.append(conn)
                clients_connected = clients_connected + 1
            else:
                data = s.recv(4)
                if not data:
                    #Interpert empty result as closed connection
                    print "closing"
                    #stop listening for input and output
                    inputs.remove(s)
                    s.close()
                    clients_connected = clients_connected - 1

    print "both connections has been established"
    inputs.remove(server)

    initiated = 0
    #making sure both of the clients got initializtion message "0000"
    while initiated < 2:
        readable, writeable, exceptional = select.select(inputs,inputs,inputs)
        for s in writeable:
            s.send("0000")
            initiated = initiated + 1
    print "game started"
    #Main loop - forwarding messages between the clients
    while inputs:
        readable, writeable, exceptional = select.select(inputs,inputs,inputs)
        #handle inputs
        for s in readable:
            if s is server:
                print "ERROR! can't initiate another connection after the game has been started!"
            #Recieve data from the client
            data = s.recv(4)
            if data:
                #A readable client socket has data
                print "recieved",data,"from",s.getpeername()
                if data != "0000":
                    #making sure the data isn't initialization message, in case it is the sever will ignore it
                    #broadcast the recived message:
                    for o in inputs:
                        if o is not s:
                            o.send(data)

            else:
                #Interpert empty result as closed connection
                print "closing"
                #stop listening for input and output
                inputs.remove(s)
                s.close()

        for s in exceptional:
            print "handling exceptions for",s.getpeername()
            inputs.remove(s)
            s.close()
希望有人会看到这个并帮助我......

0 个答案:

没有答案