tags:

views:

71

answers:

2
+1  Q: 

c# sockets help

Hi, I'm completely new to socket programming with C#, I'm trying to get two running .exes to talk to eachother:

static void Main(string[] args) {
    bool sender = !false;
    if (args.Length > 0) sender = !true;
    if (sender) {
        try {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8221);
            sock.Connect(ipe);
            while (true) {
                string toSend = Console.ReadLine();
                sock.Send(Encoding.UTF32.GetBytes(toSend));
            }
        }
        catch (SocketException e) {
            Console.WriteLine(e.Message);
            Console.ReadLine();
        }
    }
    else {
        try {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 8221);
            sock.Bind(ipe);
            sock.Listen(4);
            while (true) {
                if (!sock.Connected) continue;
                byte[] buffer = new byte[1024];
                if (sock.Receive(buffer) > 0) Console.WriteLine(Encoding.UTF32.GetString(buffer));
            }
        }
        catch (SocketException e) {
            Console.WriteLine(e.Message);
            Console.ReadLine();
        }
    }
}

At the moment though, both programs run without error, but they don't seem to connect (if (!sock.Connected) always is true).

Please help, thank you.

+2  A: 

Edit: Noticed that you don't have a sock.Accept() in your listener. You need to get a incoming socket that you can "talk on". Place a Socket c = sock.Accept() before your while(true) loop and use the c socket to send and receive data

Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 8221);
sock.Bind(ipe);
sock.Listen(4);

Socket c = sock.Accept(); // added

while (true) {
    if (!c.Connected) continue;
    byte[] buffer = new byte[1024];
    if (c.Receive(buffer) > 0) Console.WriteLine(Encoding.UTF32.GetString(buffer));
}

And; As a recommendation, whenever I make socket programs, I usually send the number of bytes that I want to send before the actual buffer. If you are able to make your sender and listener connect this might be the fix to have them exchange data.

public void send(byte[] buf) {
    socket.Send(BitConverter.GetBytes(buf.Length), SocketFlags.None);
    socket.Send(buf, buf.Length, SocketFlags.None);
}

public byte[] receive() {
    byte[] lengthBytes = new byte[4];
    int read = socket.Receive(lengthBytes);
    // read contains the number of read bytes, so we can check it if we want
    int length = BitConverter.GetInt32(lengthBytes);
    byte[] buf = new byte[length];
    socket.Receive(buf);
    return buf;
}
Patrick
I was just constructing an answer - you you got there first :) - critically, you need the Recieve function call ...
Ragster
I do have .Receive()? :)
Motig
@Motig: Yes, but instead of just receiving data without knowing what it is, you can send the number of bytes first, so your listener knows how much data it should receive.
Patrick
Oh, and as a security note, [don't trust user input](http://stackoverflow.com/questions/72394/what-should-a-developer-know-before-building-a-public-web-site/73967#73967) without sanitation. Doing so can end in Denial of Service attacks for instance.
Patrick
But Patrick, that doesn't solve the issue that I'm not getting anything at all... Or do you have to know the length to avoid some sort of error?
Motig
@Motig: But have you tried sending something as simple as an int32? Then you know the length of the receiving buffer (instead of receiving 1024 bytes, which will block until it's filled).
Patrick
Patrick, I never even get that far because sock.Connected is false.
Motig
Ah, your edit has fixed the issue for me, thanks. I just did sock = sock.Accept()... That's okay, right?
Motig
@Motig: That should work yes. Good luck with the rest :-)
Patrick
@Motig: Don't forget to mark an answer as accepted if your problem was solved.
Patrick
+1  A: 

No where in your server code you are accepting the incoming connections. You will have to accept and create a socket at the server end for the new incoming clients.

Socket newSock = sock.Accept();
if (!newSock.Connected) continue;
else
{...}
KMan