多个客户端需要多个线程吗?

时间:2017-10-29 00:24:13

标签: java multithreading sockets server client

package General;

import java.io.*;
import java.net.*;
import java.util.Scanner;


class Server
{
    public static final int PORT = 7777;    
    protected static final int HEIGHT = 525;    
    protected static final int WIDTH = 1680;    
    private double y1 = 300;    
    private double y2 = 300;    
    private Scanner scan;    
    private PrintStream printStream;    
    private ServerThread one;    
    private ServerThread two;    

    public static void main( String args[] ) throws IOException
    {
        System.out.println( "THIS IS THE RIGHT SERVER" );
        new Server().runServer();
    }


    public void runServer() throws IOException
    {
        ServerSocket serverSocket = new ServerSocket( PORT );
        System.out.println( "Server up & ready for connection..." );
        while ( true )
        {
            Socket socket = serverSocket.accept();
            new ServerThread( socket ).start();
        }
    }


    public class ServerThread extends Thread
    {
        Socket socket;

        ServerThread( Socket socket )
        {
            this.socket = socket;
        }


        public void run()
        {
            try
            {
                scan = new Scanner( socket.getInputStream() );
                printStream = new PrintStream( socket.getOutputStream() );
                System.out.println( "User " + scan.nextLine() + " has connected to the server." );
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }

            for ( int j = 0; j > -1; j++ )
            {
                System.out.println( "nope" );
                printStream.println( "not running" );
                if ( scan.nextLine().equals( "started" ) )
                {
                    printStream.println( "go" );
                    break;
                }
                System.out.println( "nope2" );
            }

            try
            {
                System.out.println( "IM OUT" );
                printStream.flush();
                String message = null;
                while ( ( message = scan.nextLine() ) != null )
                {
                    if ( message.equals( "not started" ) || message.equals( "started" ) )
                    {
                        printStream.println( "lag" );
                    }
                    else
                    {
                        System.out.println( "Incoming client message: " + message );
                        String position = message.substring( 10 );
                        double positionDouble = Double.parseDouble( position );
                        String info = message.substring( 0, 8 );
                        if ( info.equals( "p1 y pos" ) )
                        {
                            y1 = positionDouble;
                            System.out.println( y1 );
                        }
                        else if ( info.equals( "p2 y pos" ) )
                        {
                            y2 = positionDouble;
                            System.out.println( y2 );
                        }
                        if ( info.equals( "p1 y pos" ) )
                        {
                            printStream.println( y2 );
                        }
                        else if ( info.equals( "p2 y pos" ) )
                        {
                            printStream.println( y1 );
                        }
                    }
                }
                socket.close();
            }
            catch ( IOException e )
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

package General;

import java.awt.Color;
import java.io.*;
import java.net.*;
import java.util.Scanner;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class BallMover extends JPanel implements ActionListener, KeyListener
{

    JFrame jf = new JFrame();    
    Timer tm = new Timer( 1, this );    
    protected TextField tf;    
    protected Label score1;    
    protected int p1s = 0;    
    protected Label score2;    
    protected int p2s = 0;    
    protected static final int HEIGHT = 525;    
    protected static final int WIDTH = 1680;    
    protected double y1 = 300;    
    protected double y2 = 300;    
    protected double velY1 = 1.5;    
    protected double velY2 = 1.5;    
    protected double ballx = WIDTH / 2;    
    protected double bally = HEIGHT / 2;    
    protected double velBall = 1.2;    
    protected int ballAngle;    
    protected Font hehe;    
    protected static final int OFFSET = 0;    
    Socket socket;    
    PrintStream fileStream;    
    Scanner scan1;    

    public BallMover() throws IOException
    {
        socket = new Socket( "localhost", PORT );
        scan1 = new Scanner( socket.getInputStream() );
        fileStream = new PrintStream( socket.getOutputStream() );
        fileStream.println( name );

        hehe = new Font( "Ariel", Font.PLAIN, 25 );
        Rectangle instructions = new Rectangle( WIDTH / 3 - 10, OFFSET );
        instructions.setLocation( 10, 0 );
        Rectangle score1Pos = new Rectangle( WIDTH / 3, OFFSET );
        score1Pos.setLocation( WIDTH / 3, 0 );
        Rectangle score2Pos = new Rectangle( WIDTH / 3, OFFSET );
        score2Pos.setLocation( 2 * WIDTH / 3, 0 );
        Rectangle screen = new Rectangle( WIDTH, HEIGHT );
        screen.setLocation( 0, 0 );

        tf = new TextField( "", 10 );
        tf.setBounds( new Rectangle( 5, 5 ) );
        tf.setFont( hehe );
        tf.setEditable( false );
        jf.add( tf );
        tf.addKeyListener( this );

        JLabel instruct = new JLabel( convertToMultiline(
            "Press: \n0 to restart \nq to change p1 padal direction \np to change p2 padal direction \ns to pause \ncy@ once you press 0"
                + "</html>" ) );
        instruct.setBounds( instructions );
        instruct.setFont( hehe );
        // jf.add( instruct );

        score1 = new Label( "Player 1 Score: " + p1s );
        score1.setBounds( score1Pos );
        score1.setFont( hehe );
        // jf.add( score1 );

        score2 = new Label( "Player 2 Score: " + p2s );
        score2.setBounds( score2Pos );
        score2.setFont( hehe );
        // jf.add( score2 );

        jf.setSize( WIDTH, HEIGHT );
        this.setBounds( screen );
        jf.add( this );
        jf.setTitle( "BallMover1" );
        jf.setVisible( true );

        if ( Math.random() > .5 )
        {
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 315;
            }
            else
            {
                ballAngle = (int)( Math.random() ) + 45;
            }
        }
        else
        {
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 135;
            }
            else
            {
                ballAngle = (int)( Math.random() * 45 ) + 180;
            }
        }
        String command;
        while ( true )
        {
            command = scan1.nextLine();
            fileStream.println( "not started" );
            System.out.println( command );
            if ( command.equals( "go" ) )
            {
                break;
            }
        }
        fileStream.flush();
    }


    public void paintComponent( Graphics g )
    {
        super.paintComponent( g );
        g.setColor( Color.RED );
        g.fillRect( 30, (int)y1, 30, 200 );
        g.fillRect( WIDTH - 80, (int)y2, 30, 200 );
        g.fillOval( (int)ballx, (int)bally, 40, 40 );
        g.drawLine( 0, OFFSET, WIDTH, OFFSET );
    }


    @Override
    public void keyTyped( KeyEvent e )
    {
        char input = e.getKeyChar();
        if ( input == 's' )
        {
            if ( tm.isRunning() )
            {
                tm.stop();
            }
            else
            {
                tm.start();
            }
        }
        if ( input == 't' )
        {
            System.out.println( "ballx: " + ballx );
            System.out.println( "bally: " + bally );
            System.out.println( "delta x: " + velBall * Math.cos( Math.toRadians( ballAngle ) ) );
            System.out.println( "delta y: " + velBall * Math.sin( Math.toRadians( ballAngle ) ) );
            System.out.println( "ball angle: " + ballAngle );

        }
        if ( input == '0' )
        {
            velBall = 1.05;
            ballx = WIDTH / 2;
            bally = HEIGHT / 2;
            fileStream.println( "started" );
            tm.start();
        }
        if ( input == 'q' )
        {
            velY1 *= -1;
        }
    }


    @Override
    public void keyPressed( KeyEvent e )
    {
    }


    @Override
    public void keyReleased( KeyEvent e )
    {
    }


    @Override
    public void actionPerformed( ActionEvent e )
    {
        System.out.println( "ballx: " + ballx );
        System.out.println( "bally: " + bally );
        System.out.println( "delta x: " + velBall * Math.cos( Math.toRadians( ballAngle ) ) );
        System.out.println( "delta y: " + velBall * Math.sin( Math.toRadians( ballAngle ) ) );
        System.out.println( "ball angle: " + ballAngle );
        System.out.println( "" );
        if ( y1 + 210 > HEIGHT || y1 <= OFFSET ) // p1 padal
        {
            if ( y1 <= OFFSET )
            {
                y1 = 5 + OFFSET;
            }
            velY1 *= -1;
        }
        if ( y2 + 210 > HEIGHT || y2 <= OFFSET )// p2 padal
        {
            if ( y2 <= OFFSET )
            {
                y2 = 5 + OFFSET;
            }
            velY2 *= -1;
        }
        y1 = y1 + velY1;
        y2 = y2 + velY2;
        if ( ballx < 70 && ballx > 40 && bally >= y1 && bally <= y1 + 200 ) // bounce
                                                                            // off
                                                                            // p1
        {
            System.out.println( "bdoink1" );
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 315;
            }
            else
            {
                ballAngle = (int)( Math.random() ) + 45;
            }
            velBall += .03;
        }

        if ( ballx > WIDTH - 100 && ballx < WIDTH - 70 && bally >= y2 && bally <= y2 + 200 ) // bounce
                                                                                             // off
                                                                                             // p2
        {
            System.out.println( "bdoink2" );
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 135;
            }
            else
            {
                ballAngle = (int)( Math.random() * 45 ) + 180;
            }
            velBall += .03;
        }

        if ( ballx < 0 ) // Player 2 Wins
        {
            p2s++;
            score2.setText( "Player 2 Score: " + p2s );
            tm.stop();
        }
        if ( ballx > WIDTH ) // Player 1 Wins
        {
            p1s++;
            score1.setText( "Player 1 Score: " + p1s );
            tm.stop();
        }
        if ( bally > HEIGHT - 50 || bally <= OFFSET ) // touches bottom or top
                                                      // wall
        {
            if ( bally <= OFFSET )
            {
                bally = 5 + OFFSET;
            }
            ballAngle *= -1;
        }
        ballx += velBall * Math.cos( Math.toRadians( ballAngle ) );
        bally += velBall * Math.sin( Math.toRadians( ballAngle ) );

        // send info to server
        System.out.println( "hi1" );
        fileStream.println( "p1 y pos: " + y1 );
        System.out.println( "hi2" );
        String work = scan1.nextLine();
        System.out.println( "hi3" );
        if ( work.equals( "lag" ) )
        {
            System.out.println( "hi4" );
        }
        else
        {
            y2 = Double.parseDouble( work );
        }
        System.out.println( "hi5" );
        repaint();

    }


    public static String convertToMultiline( String orig )
    {
        return "<html>" + orig.replaceAll( "\n", "<br>" );
    }

    // Client
    public static final int PORT = 7777;

    protected static final String name = "client1";


    public static void main( String args[] ) throws IOException
    {
        new BallMover();
    }
}

package General;

import java.awt.Color;
import java.io.*;
import java.net.*;
import java.util.Scanner;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;


public class BallMover2 extends JPanel implements ActionListener, KeyListener
{

    JFrame jf = new JFrame();    
    Timer tm = new Timer( 1, this );    
    protected TextField tf;    
    protected Label score1;    
    protected int p1s = 0;    
    protected Label score2;    
    protected int p2s = 0;    
    protected static final int HEIGHT = 525;    
    protected static final int WIDTH = 1680;    
    protected double y1 = 300;    
    protected double y2 = 300;    
    protected double velY1 = 1.5;    
    protected double velY2 = 1.5;    
    protected double ballx = WIDTH / 2;    
    protected double bally = HEIGHT / 2;    
    protected double velBall = 1.2;    
    protected int ballAngle;    
    protected Font hehe;    
    protected static final int OFFSET = 0;    
    Socket socket;    
    PrintStream fileStream;    
    Scanner scan1;    

    public BallMover2() throws IOException
    {
        socket = new Socket( "localhost", PORT );
        scan1 = new Scanner( socket.getInputStream() );
        fileStream = new PrintStream( socket.getOutputStream() );
        fileStream.println( name );

        hehe = new Font( "Ariel", Font.PLAIN, 25 );
        Rectangle instructions = new Rectangle( WIDTH / 3 - 10, OFFSET );
        instructions.setLocation( 10, 0 );
        Rectangle score1Pos = new Rectangle( WIDTH / 3, OFFSET );
        score1Pos.setLocation( WIDTH / 3, 0 );
        Rectangle score2Pos = new Rectangle( WIDTH / 3, OFFSET );
        score2Pos.setLocation( 2 * WIDTH / 3, 0 );
        Rectangle screen = new Rectangle( WIDTH, HEIGHT );
        screen.setLocation( 0, 0 );

        tf = new TextField( "", 10 );
        tf.setBounds( new Rectangle( 5, 5 ) );
        tf.setFont( hehe );
        tf.setEditable( false );
        jf.add( tf );
        tf.addKeyListener( this );

        JLabel instruct = new JLabel( convertToMultiline(
            "Press: \n0 to restart \nq to change p1 padal direction \np to change p2 padal direction \ns to pause \ncy@ once you press 0"
                + "</html>" ) );
        instruct.setBounds( instructions );
        instruct.setFont( hehe );
        // jf.add( instruct );

        score1 = new Label( "Player 1 Score: " + p1s );
        score1.setBounds( score1Pos );
        score1.setFont( hehe );
        // jf.add( score1 );

        score2 = new Label( "Player 2 Score: " + p2s );
        score2.setBounds( score2Pos );
        score2.setFont( hehe );
        // jf.add( score2 );

        jf.setSize( WIDTH, HEIGHT );
        this.setBounds( screen );
        jf.add( this );
        jf.setTitle( "BallMover2" );
        jf.setVisible( true );

        if ( Math.random() > .5 )
        {
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 315;
            }
            else
            {
                ballAngle = (int)( Math.random() ) + 45;
            }
        }
        else
        {
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 135;
            }
            else
            {
                ballAngle = (int)( Math.random() * 45 ) + 180;
            }
        }
        String command;
        while ( true )
        {
            command = scan1.nextLine();
            fileStream.println( "not started" );
            System.out.println( command );
            if ( command.equals( "go" ) )
            {
                break;
            }
        }
        fileStream.flush();
    }


    public void paintComponent( Graphics g )
    {
        super.paintComponent( g );
        g.setColor( Color.RED );
        g.fillRect( 30, (int)y1, 30, 200 );
        g.fillRect( WIDTH - 80, (int)y2, 30, 200 );
        g.fillOval( (int)ballx, (int)bally, 40, 40 );
        g.drawLine( 0, OFFSET, WIDTH, OFFSET );
    }


    @Override
    public void keyTyped( KeyEvent e )
    {
        char input = e.getKeyChar();
        if ( input == 's' )
        {
            if ( tm.isRunning() )
            {
                tm.stop();
            }
            else
            {
                tm.start();
            }
        }
        if ( input == 't' )
        {
            System.out.println( "ballx: " + ballx );
            System.out.println( "bally: " + bally );
            System.out.println( "delta x: " + velBall * Math.cos( Math.toRadians( ballAngle ) ) );
            System.out.println( "delta y: " + velBall * Math.sin( Math.toRadians( ballAngle ) ) );
            System.out.println( "ball angle: " + ballAngle );

        }
        if ( input == '0' )
        {
            velBall = 1.05;
            ballx = WIDTH / 2;
            bally = HEIGHT / 2;
            fileStream.println( "started" );
            tm.start();
        }
        if ( input == 'p' )
        {
            velY2 *= -1;
        }
    }


    @Override
    public void keyPressed( KeyEvent e )
    {
    }


    @Override
    public void keyReleased( KeyEvent e )
    {
    }


    @Override
    public void actionPerformed( ActionEvent e )
    {
        System.out.println( "ballx: " + ballx );
        System.out.println( "bally: " + bally );
        System.out.println( "delta x: " + velBall * Math.cos( Math.toRadians( ballAngle ) ) );
        System.out.println( "delta y: " + velBall * Math.sin( Math.toRadians( ballAngle ) ) );
        System.out.println( "ball angle: " + ballAngle );
        System.out.println( "" );
        if ( y1 + 210 > HEIGHT || y1 <= OFFSET ) // p1 padal
        {
            if ( y1 <= OFFSET )
            {
                y1 = 5 + OFFSET;
            }
            velY1 *= -1;
        }
        if ( y2 + 210 > HEIGHT || y2 <= OFFSET )// p2 padal
        {
            if ( y2 <= OFFSET )
            {
                y2 = 5 + OFFSET;
            }
            velY2 *= -1;
        }
        y1 = y1 + velY1;
        y2 = y2 + velY2;
        if ( ballx < 70 && ballx > 40 && bally >= y1 && bally <= y1 + 200 ) // bounce
                                                                            // off
                                                                            // p1
        {
            System.out.println( "bdoink1" );
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 315;
            }
            else
            {
                ballAngle = (int)( Math.random() ) + 45;
            }
            velBall += .03;
        }

        if ( ballx > WIDTH - 100 && ballx < WIDTH - 70 && bally >= y2 && bally <= y2 + 200 ) // bounce
                                                                                             // off
                                                                                             // p2
        {
            System.out.println( "bdoink2" );
            if ( Math.random() > .5 )
            {
                ballAngle = (int)( Math.random() * 45 ) + 135;
            }
            else
            {
                ballAngle = (int)( Math.random() * 45 ) + 180;
            }
            velBall += .03;
        }

        if ( ballx < 0 ) // Player 2 Wins
        {
            p2s++;
            score2.setText( "Player 2 Score: " + p2s );
            tm.stop();
        }
        if ( ballx > WIDTH ) // Player 1 Wins
        {
            p1s++;
            score1.setText( "Player 1 Score: " + p1s );
            tm.stop();
        }
        if ( bally > HEIGHT - 50 || bally <= OFFSET ) // touches bottom or top
                                                      // wall
        {
            if ( bally <= OFFSET )
            {
                bally = 5 + OFFSET;
            }
            ballAngle *= -1;
        }
        ballx += velBall * Math.cos( Math.toRadians( ballAngle ) );
        bally += velBall * Math.sin( Math.toRadians( ballAngle ) );

        // send info to server
        System.out.println( "hi1" );
        fileStream.println( "p2 y pos: " + y2 );
        System.out.println( "hi2" );
        String work = scan1.nextLine();
        System.out.println( "hi3" );
        if ( work.equals( "lag" ) )
        {
            System.out.println( "hi4" );
        }
        else
        {
            y1 = Double.parseDouble( work );
        }
        System.out.println( "hi5" );
        repaint();

    }


    public static String convertToMultiline( String orig )
    {
        return "<html>" + orig.replaceAll( "\n", "<br>" );
    }

    // Client
    public static final int PORT = 7777;

    protected static final String name = "client2";


    public static void main( String args[] ) throws IOException
    {
        new BallMover2();
    }
}

我正在尝试与2个不同的客户进行乒乓球比赛。我制作了一台服务器,可以从两个踏板上收集信息并经常更新踏板位置。每当我用2个客户端运行我的代码时,第一个客户端就会停止向服务器提供信息。我想知道多个客户端是否需要多个线程。如果是这样,怎么样?感谢。

0 个答案:

没有答案