sr

Does this have any special significance? I have made a serverSocket and a socket, and I send the message “beep” as a test form the server to the client which are both on localhost. For some reason after beep it gets the message “sr” though I never send that message.

I get a bindalready in use exception and I am using port 64652. Does that mean the socket is already taken or whats going on now. Also I have no idea what code to show if any.

As a side note I chose 64652 because it spells ninja on a phone.

don’t know about “sr”, post code where you send/receive data.

[quote]I get a bindalready in use exception
[/quote]
this happens if you bind to port once and try to do it again. Common if you run server app, put it in background and forget about it, so you run another server app which throws that exception then.

p.s. … speaking of ninjas, maybe we have some here? :wink:

Nice avatar ;D. I figured the bind exception was pointless since I was getting it all the time on my multiple chat clients and it was working fine.

I supose I could just try other ports and maybe it will go away? I guess i’ll do that. Starting with 646527 ninjas! (out of range :()

I searched my project and an s does not appear in my code followed by an r except once in the center of a variable. So yea…

Edit: So no matter the port my message gets sent, then sr goes through.
Ill post my code later when I have time.

Edit: another unrelated problem is that I couldn’t find a book I liked that detailed game programming specifically, so I figured out how to connect sockets and am trying to reinvent the wheel. So far its square.

Code

My handy dandy Socket subclass

import java.nio.*;
import java.io.*;
import java.net.*;

public class SocketAction extends Thread    {

    private DataInputStream inStream = null;
    protected PrintStream outStream = null;
    protected ObjectOutput out = null;
    private Socket socket = null;
    private String initMessage = null;
    
    public SocketAction(Socket sock, String initMessage) {
        this(sock);
        initMessage = null;
    }
    
    public SocketAction(Socket sock) {
        super("SocketAction");
        try {
            inStream = new DataInputStream(new
                BufferedInputStream(sock.getInputStream(), 64652));
            outStream = new PrintStream(new
                BufferedOutputStream(sock.getOutputStream(), 64652), true);
            socket = sock;
            out = new ObjectOutputStream(outStream);
        }
        catch (IOException e) {
            System.out.println("Couldn't initialize SocketAction: " + e);
            System.exit(1);
        }
    }
    
    public String getInitMessage() {
        return initMessage;
    }
    
    public void send(String s) {
        outStream.println(s);
    }
    
    public void send(Object o) throws IOException {
        out.writeObject(o);
    }

    public String receive() throws IOException {
        return inStream.readLine();
    }
    
    
    public boolean isConnected() {
        return ((inStream != null) && (outStream != null) && (socket != null));
    }
    
    protected void finalize () {
        if (socket != null) {
        try {
            socket.close();
        }
        catch (IOException e) {
            System.out.println("Couldn't close socket: " + e);
            }
        socket = null;
        }
    }
    
    public void closeConnections() {
        try {
            socket.close();
            socket = null;
        }
        catch (IOException e) {
            System.out.println("Couldn't close socket: " + e);
        }
    }
}

GameManager

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.midi.*;

import java.io.*;
import javax.sound.sampled.*;
import java.text.DecimalFormat;
import java.net.*;
import java.nio.*;

public class GameManager extends GameCanvas {
    public static GameManager INSTANCE = new GameManager();
    public static final int PORT = 64652; //spells ninja on a phone ^^
    public static final String ADDR = "localhost";
    
    private SocketAction host;
    private int fps;
    private SpriteManager sm = SpriteManager.INSTANCE;
    private ClientListener cl = ClientListener.INSTANCE;
    private HostListener hl;
    private String lastMessage;
    
    public void init(String type) {
        try {
            if (type.equals("host")) {
                ClientListener cl = new ClientListener();
                host = new SocketAction(new Socket(ADDR, PORT));
            }
            else if (type.equals("client")) {
                host = new SocketAction(new Socket(ADDR, PORT));
                sm = null;
                cl = null;
            }
            hl = new HostListener(host);
        }
        catch (IOException e) {
            System.err.println(e);
        }
    }
    
    public synchronized void setLastMessage(String message) {
        lastMessage = message;
    }

    public void Update(long elapsedTime) {
        cl.sendString("beep");
        if (elapsedTime > 0) {
            fps = (int) (1000L / elapsedTime);
        }
        try {
            if (cl != null) {
                cl.sendObject(sm); 
            }
        }
        catch (IOException e) {
            System.err.println(e);
        }
        
        synchronized (lastMessage) {
            System.out.println("Last Message: " + lastMessage);
        }
    }

    public void draw(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(
            RenderingHints.KEY_TEXT_ANTIALIASING,
            RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // Render game here
        g.setColor(Color.GREEN);
        g.fillRect(0, 0, getWidth(), getHeight());

        // Display data
        g.setColor(Color.WHITE);
        g.setFont(new Font("Dialog", Font.PLAIN, 18));
        g.drawString("FPS: " + fps, getWidth() - 90, getHeight() - 10);
    }
}

Thingy that listens for clients trying to connect and adds them to a list

import java.nio.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.awt.*;

public class ClientAdder extends Thread {
    
    private ServerSocket serv;
    private ClientListener cl;
    
    public ClientAdder(ServerSocket serv, ClientListener c) {
        this.serv = serv;
        cl = c;
    }
    
    public void run() {
        while (true) {
            try {
                SocketAction sock = new SocketAction(serv.accept());
                cl.addPlayer(new Player(sock, new Sprite(Color.red)));
            }
            catch (IOException e) {
                System.err.println(e);
            }
        }
    }
}

Thingy that listens to the clients for input information

import java.nio.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.awt.*;


public class ClientListener extends Thread {

    public static ClientListener INSTANCE = new ClientListener();

    private ClientAdder ca;
    private ServerSocket serv;
    private LinkedList<Player> players;
    
    public ClientListener() {
        try {
            serv = new ServerSocket(GameManager.PORT);
            ca = new ClientAdder(serv, this);
            ca.start();
        }
        catch (IOException e) {
            System.err.println(e);
        }
        
        players = new LinkedList<Player>();
        start();
    }
    
    public void run() {
        while (true) {
            try {
                synchronized (players) {
                    for (Player p : players) {
                        String action = p.getSock().receive();
                        if (action != null) {
                            p.addAction(action);
                        }
                    }
                }
                Thread.sleep(10);
            }
            catch (IOException e) {
                System.err.println(e);
            }
            catch (InterruptedException e) {
                System.err.println(e);
            }
        }
    }
    
    public synchronized void addPlayer(Player p) {
        players.add(p);
    }
    
    public synchronized void sendString(String s) {
        for (Player p : players) {
            p.getSock().send(s);
        }
    }
    
    public synchronized void sendObject(Object o) throws IOException {
        for (Player p : players) {
            p.getSock().send(o);
        }
    }
}

My “player” class which i really have no idea where I am going with

import java.util.*;

public class Player {
    private LinkedList<String> actionsLine;
    private Sprite sprite;
    private SocketAction sock;
    
    public Player(SocketAction sock, Sprite sprite) {
        actionsLine = new LinkedList<String>();
        this.sock = sock;
        this.sprite = sprite;
    }
    
    public SocketAction getSock() {
        return sock;
    }
    
    public Sprite getSprite() {
        return sprite;
    }
    
    public void addAction(String s) {
        actionsLine.add(s);
    }
    
    public String proccessFirstAction() {
        String action = actionsLine.get(0);
        actionsLine.remove(0);
        return action;
    }
}

The Idea I came up with was to have the client and host applicatins differ by simply having a socket point either to another machine or to itself. If certain variables aren’t null then it gets input from clients and then sends it out, treating itself as a client which I know is stupid but I couldn’t think of any other way.

Anyway if I run it with the arg “host” it makes a clientListener and clientAdder which hold the ServerSocket. In the init I attatch a socket to itself because I am a genius. In the update method I send the message “beep” to all clients. The clients, the only one is the host itself, is recieving “q~beep”. Also “sr” is being sent sometime between the init method and the first update.

Feel free to point me to a good reference (which I havn’t managed to find) for good ways to organize this.

How is it working fine when you receive exceptions? :slight_smile:
You didn’t understood… the exception is thrown becouse you are trying to bind to a port that you already bind to or is already bind by another program. Chances that port 64652 is in use are extreamly slim (it’s free at my computer). You can check if port is in use with an average firewall. It’s 99% that you are binding the port twice.

It all depends how are you reading your messages. Maybe you are sending numbers (bytes, ints…) and reading them as characters, so you see you don’t have to actually send “sr” to read it.

find a NIO tutorial for a simple chat server/client. It’s all you need to get started, to learn how to send and receive messages.

About the code you posted… I never worked with streams and blocking IO, only NIO, Channels and ByteBuffers so I don’t understand clearly most of it.

Why is SocketAction extending Thread? No run() overriden and no start() called. Why at all extend Thread, why not implement Runnable instead as you don’t really need all Thread functionality?

I’ve look but I couldn’t find why you get “sr” extra… You didn’t post HostListener class. If it has any ServerSocket binds in it then it is the reason why you get “bind already in use” exception.
Also, I see that you are connecting server to itself for testing. This isn’t a bad idea, but the better one is to run another instance of your app to act like a client and then to connect to first app you run (server). So it’s like this, first you run your app once and start server mode (waiting for connections, without connecting to yourself), then you run second app (seperatly!) and start client mode (connect to yourself, that is first app).

this is the only way you receive data?

String action = p.getSock().receive(); 

so here you send “beep” and an object if it’s in server mode?:

        cl.sendString("beep");
        if (cl != null) {
            cl.sendObject(sm); 

so could it be that your “sr” is from this sendObject()? I can’t tell where you receive and process object you sent here. Try commenting this.

Good luck with this.

You’ll need to trace down the sr. Make some outputs or a logfile or so to find out where or when it comes.

Maybe it has something to do with data streams, try to use string / character streams like Reader and Writer classes. The strange things you get could be additionally control information send by one stream but read wrong by the receiver.

-JAW

I don’t know why I extended Thread.

The Bind exception thing I thought was fine because on my earlier chat client thingy I would get it for every connection but they still connected and functioned properly.
OK nevermind it turns out im a liar, I just went back and tried it again and there was no exeption about bind. Just in this app. Well good times for halucinations.

HostListener

import java.nio.*;
import java.io.*;
import java.net.*;

public class HostListener extends Thread {
    
    SocketAction host;
    
    public HostListener(SocketAction sock) {
        host = sock;
        start();
    }
    
    
    public void run() {
        while (true) {
            try {
                String message = host.receive();
                if (message != null) {
                    GameManager.INSTANCE.setLastMessage(message);
                }
            }
            catch (IOException e) {
                System.err.println(e);
            }
        }
    }
}

Noting out that line of code removed the sr from being sent, and also changed q~beep to beep so yay. Although that means my object serializer/sender is horribly broken.
Still looking for why that bind exception is being thrown.

Thanks for the responces thus far, very helpful. Removed the extend Thread part ::slight_smile: