0

I'm trying to collect data from a IP Address and Port using a TCP Client or a socket, but can't seem to find a way to successfully write what I receive to either the Console or to a file. Of the numerous sources I've sifted through online including MSDN documentation and various blogs, I found this one to be the most understandable, yet it still doesn't write anything to the console and I know the IP Address / Port (which I can't share) is supposed to be sending me a stream of data.

What am I doing wrong?

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TCPIPChallenge
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Client client = new Client();
            client.SetupServer();
        }
    }

    public class Client
    {

        private Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private byte[] _recieveBuffer = new byte[8142];

        private void SetupServer()
        {
            try
        {
            _clientSocket.Connect(new IPEndPoint(IPAddress.Parse("0.0.0.0"), 8888));
            Console.WriteLine("It was successful!");
        }
        catch (SocketException ex)
        {
            Console.WriteLine("There was an issue...");
            Debug.Write(ex.Message);
        }
        Console.WriteLine(_clientSocket.Connected);
        _clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);

    }

    private void ReceiveCallback(IAsyncResult AR)
    {
        //Check how much bytes are recieved and call EndRecieve to finalize handshake
        int recieved = _clientSocket.EndReceive(AR);
        Console.WriteLine(_clientSocket.Connected);
        if (recieved <= 0)
            return;

            //Copy the recieved data into new buffer , to avoid null bytes
            byte[] recData = new byte[recieved];
            Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);

            //Process data here the way you want , all your bytes will be stored in recData
            Console.WriteLine(recData.ToString());

            //Start receiving again
            _clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
        }
    }
}
springathing
  • 425
  • 3
  • 8
  • 28
  • What is happening? – PepitoSh Jun 12 '18 at 01:51
  • Nothing at all, it opens the console and closes it without displaying any information from the IP Address...assuming my logic is written properly for a successful connection to the IP address of interest – springathing Jun 12 '18 at 01:54

2 Answers2

1

It seems you are not waiting for the result to be displayed. Put a Console.Read(); in your Main.

public static void Main(string[] args)
        {
            Client client = new Client();
            client.SetupServer();
            Console.Read();
        }
PepitoSh
  • 1,774
  • 14
  • 13
  • I put some Console.WriteLine's to see if the connection is successful and it never hits the catch block. Does this mean the IP Address actually isn't sending any data? – springathing Jun 12 '18 at 02:00
  • Is the connection potentially closing out too early? Or not being held open for long enough for the data to start being parsed through? – springathing Jun 12 '18 at 02:00
  • Your SetupServer call returns and the ReceiveCallback never gets called. This is why you have to wait for something to happen on the line. – PepitoSh Jun 12 '18 at 02:04
  • It seems to not be getting past that (received <= 0) check therefore it wouldn't even be able to try again to receive. Waiting at a Console.ReadLine() wouldn't actually help it connect, right? – springathing Jun 12 '18 at 02:11
  • if your code never gets to if (recieved <= 0), then nothing is received. – PepitoSh Jun 12 '18 at 02:56
1

This seems like the suspect here:

Console.WriteLine(recData.ToString());

You can't just call ToString on a byte array expecting it to turn into a string because there are many different types of encoding that can convert bytes into string and vice versa. Some encoding takes more bytes than others, like UTF-8 and UTF-16 for example.

Example using Unicode encoding

Converting your message to bytes:

byte[] data = System.Text.Encoding.Unicode.GetBytes("Hello!");

Displaying the data again:

byte[] recData = new byte[recieved];
string message = System.Text.Encoding.Unicode.GetString(recData);
Console.WriteLine(message); // "Hello!"

Ensure that you use similar encoding on both server and client side to get consistant data.

Different encoding types: UTF-8, UTF-16, and UTF-32

Swift
  • 3,250
  • 1
  • 19
  • 35
  • I added that bit of code, unfortunately it never seems to actually reach that code which I assume is due to there not being any connection with the IP address that I'm using, even though it should be sending me data... Is there any other tricks I could try to MAKE CERTAIN that it is just the connection? – springathing Jun 13 '18 at 02:09
  • Can you put a `Console.WriteLine(clientSocket.Connected)` after your connect call? Does it say connected? – Swift Jun 13 '18 at 03:22
  • I added the Console.WriteLine's, it displays true before the _clientSocket.BeginReceive(... portion but doesn't display anything else. When I used telnet to the IP Address and Port there was a successful connection, but no data was appearing on my CMD console – springathing Jun 13 '18 at 03:31
  • So there is something wrong with my ReceiveCallBack – springathing Jun 13 '18 at 03:32
  • The callback looks fine to me. Maybe you can post the server side code too? – Swift Jun 13 '18 at 03:35
  • Can we do a private chat? – springathing Jun 13 '18 at 03:36
  • Sure but SO doesn't have a private chat, what platform do you recommend? – Swift Jun 13 '18 at 03:42