Author Topic: [C#] Help with socket connections  (Read 5906 times)

0 Members and 1 Guest are viewing this topic.

Offline GameSnake

  • News hound
  • Hero Member
  • *****
  • Posts: 2937
    • View Profile
[C#] Help with socket connections
« on: August 13, 2005, 09:50:49 pm »
I am adding telnet connections to a IRC bot I'm working on for my dual enrollment project, you can chat on telnet/IRC and it features dual moderation, yadda yadda I am not announcing a project I just need some help with my coding:

My code can connect and Send, but Receive cannot get the replied
My client is a Windows machine. From this I create a socket connection to an IP and a port on a server machine. On the client machine I can manually telnet to the server, Send/Receive message like this:

Send: telnet IP Port
Receive: Connected to IP...
Send: Operation=TotalRecords
Receive: TotalRecords=1000

The fact that I can connect/Send/Receive suggests there is no access issue (the server is a linux machine).

Now here is my socket code. I can Connect and Send ("Operation=TotalRecords"). But Receive keep on waiting but never getting the message "TotalRecords=1000".

How do I code to receive the reply?

IPAddress remoteIPAddress = IPAddress.Parse(LinuxIPAddress);
EndPoint ep = new IPEndPoint(remoteIPAddress, 4321);
Socket sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
string query="Operation=TotalRecords";
sock.Connect(ep);
Encoding ASCII = Encoding.ASCII;
Byte[] ByteGet = ASCII.GetBytes(query);
Byte[] RecvBytes = new Byte[256];
int iTx=sock.Send(ByteGet, ByteGet.Length, 0); //the code worked to this point
Int32 bytes = sock.Receive(RecvBytes, RecvBytes.Length, 0); //this will wait forever...

« Last Edit: September 14, 2005, 11:00:07 pm by MyndFyre[x86] »

Offline GameSnake

  • News hound
  • Hero Member
  • *****
  • Posts: 2937
    • View Profile
Re: Help with socket connections
« Reply #1 on: August 17, 2005, 01:03:58 pm »
C'mon, MindFyre, iago??

Offline rabbit

  • x86
  • Hero Member
  • *****
  • Posts: 8092
  • I speak for the entire clan (except Joe)
    • View Profile
Re: [C] Help with socket connections
« Reply #2 on: August 17, 2005, 05:33:18 pm »
It's C++, based off of iago and DarkMinion's code, but it's pretty close to what I assume you want:
Code: [Select]
void h_socket::waitEvents()
{
long clientToken = GetTickCount();
char serverToken[4] = "";
char mpqFile[256] = "";
char checksumFormula[256];
char buffer[20000] = "";
char exeinfo[256] = "";
unsigned long version;
unsigned long checksum;
unsigned long *prodVal;
unsigned long *publicVal;
unsigned long *privateVal;
PacketBuffer pbuff;

send(s, "\x1", 1, 0);
pbuff.insert((int)0x00);
pbuff.insert(PLATID_IX86);
pbuff.insert(CLIENT_STAR);
pbuff.insert((int)0xcd);
pbuff.insert((int)0x00);
pbuff.insert((int)0x00);
pbuff.insert((int)0x00);
pbuff.insert((int)0x00);
pbuff.insert((int)0x00);
pbuff.insert("USA");
pbuff.insert("United States");
pbuff.sendpacket(s, 0x50);
while(bncsConnected)
{
DWORD waitresult = WaitForSingleObject(events[0], 10);
if(waitresult == WAIT_OBJECT_0)
{
int buflen = 0;
int packetlen = 0;
char packetdata[5000] = "";
int recvlen = recv(s, buffer + buflen, sizeof(buffer) - buflen, 0);

if(!recvlen || recvlen == SOCKET_ERROR)
{
bncsConnected = false;
Disconnect();
h_timestamp();
printf("socket closed; recvlen %i\n", recvlen);
break;
}
buflen += recvlen;
while((int)buflen >= 4 && bncsConnected && (unsigned char)buffer[0] == 0xff)
{
char packetid = buffer[1];
packetlen = *(unsigned short *)(buffer + 2);
memcpy(packetdata, buffer, packetlen);

switch(packetid)
{
case SID_NULL:
pbuff.sendpacket(s, SID_NULL);
break;

case SID_PING:
pbuff.insert((int)(*(unsigned long *)(buffer + 4)));
pbuff.sendpacket(s, 0x25);
break;

case SID_AUTH_INFO:
h_timestamp();
if(*(unsigned long *)(packetdata + 4) == 0)
{
printf("Logon type is broken SHA-1\n");
}else if(*(unsigned long *)(packetdata + 4) == 1) {
printf("Logon type is NLS 1; this should not be!  Aborting logon\n");
Disconnect();
} else if(*(unsigned long *)(packetdata + 4) == 2) {
printf("Logon type is NLS 2\n");
}

strcpy(serverToken, packetdata + 8);
strcpy(mpqFile, packetdata + 24);
strcpy(checksumFormula, packetdata + 37);

h_timestamp();
printf("Server Token: 0x");
hexStr(4, serverToken);
printf("\n");

h_timestamp();
printf("MPQ File: %s\n", mpqFile);

h_timestamp();
printf("Checksum Formula: %s\n", checksumFormula);

pbuff.clear();
pbuff.insert((int)clientToken);

h_timestamp();
if(!CheckRevision(
".\\star\\starcraft.exe",
".\\star\\storm.dll",
".\\star\\battle.snp",
checksumFormula,
&version,
&checksum,
exeinfo,
mpqFile
))
{
printf("CheckRevision() call failed; invalid hashes\n");
Disconnect();
break;
}
printf("CheckRevision() call passed\n");

pbuff.insert(version);
pbuff.insert(checksum);
pbuff.insert((int)1);
pbuff.insert((int)0);

h_timestamp();
if(DecodeCDKey(cfg.cdkey, prodVal, publicVal, privateVal) == false)
{
printf("CD-Key decode failed\n");
Disconnect();
break;
}
printf("CD-Key decode passed\n");

pbuff.insert((int)strlen(cfg.cdkey));
pbuff.insert(*(unsigned long *)prodVal);
pbuff.insert(*(unsigned long *)publicVal);
pbuff.insert((int)0);
pbuff.insert(*(unsigned long *)privateVal);

break;
default:
hexDump(packetlen, packetdata);
}

ZeroMemory(buffer, 20000);
ZeroMemory(packetdata, 5000);
packetlen = 0;
}
}
}
return;
}

Offline GameSnake

  • News hound
  • Hero Member
  • *****
  • Posts: 2937
    • View Profile
Re: [C] Help with socket connections
« Reply #3 on: August 17, 2005, 08:58:15 pm »
I have a hard time understanding that code but when I get on my other computer I'll see if it compiles and runs with my modules, which were written in C#, I don't know if it's totally cross platform.

Offline rabbit

  • x86
  • Hero Member
  • *****
  • Posts: 8092
  • I speak for the entire clan (except Joe)
    • View Profile
Re: [C] Help with socket connections
« Reply #4 on: August 18, 2005, 06:53:04 pm »
You'll need more code than that.  hexDump(), h_timestamp(), Disconnect() etc.. are in my other code somewhere, and you'll need windows.h and stdlib.h (maybe?) too.

Offline GameSnake

  • News hound
  • Hero Member
  • *****
  • Posts: 2937
    • View Profile
Re: [C] Help with socket connections
« Reply #5 on: August 18, 2005, 08:29:45 pm »
This is becoming a pain in the rear. If you have all the includes please just zip them and send what I need to get a module running. My project is due soon, I will probly just slap a GUI on this and add it to the rest of my bot, I'm not trying to connect to battle.net, just telent and IRC.

Offline MyndFyre

  • Boticulator Extraordinaire
  • x86
  • Hero Member
  • *****
  • Posts: 4540
  • The wait is over.
    • View Profile
    • JinxBot :: the evolution in boticulation
Re: Help with socket connections
« Reply #6 on: August 18, 2005, 11:15:47 pm »
C'mon, MindFyre, iago??
OMG I didn't know this was anything to do with C#.  Your topic title [C] threw me off.

You have a few different approaches to take.

The easiest is to use a NetworkStream object and then use a StreamReader/StreamWriter on top of it.  For example (you need the following namespaces: System.Net, System.Net.Sockets, System.IO, System.Text, System.Threading):
Code: [Select]
private NetworkStream m_ns;
private StreamReader m_sr;
private StreamWriter m_sw;
private Thread m_tdListener;
private bool m_open;

public delegate void TextEventHandler(string text);
public event TextEventHandler TextReceived;
protected virtual void OnTextReceived(string text) {
  if (TextReceived != null)
    TextReceived(text);
}

public void Connect(EndPoint ep) {
  Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  m_ns = new NetworkStream(sck, true);
  m_sr = new StreamReader(ns, Encoding.ASCII);
  m_sw = new StreamWriter(ns, Encoding.ASCII);

  sck.Connect(ep);

  m_open = true;

  m_tdListener = new Thread(new ThreadStart(SocketListenLoop));
  m_tdListener.IsBackground = true;
  m_tdListener.Priority = ThreadPriority.BelowNormal;

  m_tdListener.Start();
}

private void SocketListenLoop() {
  while (m_open)
  {
    string text = m_sr.ReadLine();
    OnTextReceived(text);
  }
}

public void Disconnect() {
  m_open = false;
  // abort the thread but don't let the exception run amok
  try { m_tdListener.Abort(); } catch {}
  m_sr.Close();
  m_sw.Close();
  m_ns.Close(); // you'll need to create a new Socket and NetworkStream; might as well just dispose this entire object.
}

public void Send(string text) {
  m_sw.WriteLine(text);
}
This assumes you're using a text-only protocol.  For more complicated binary protocols, you'll need to access a byte stream.  You can control your own buffer using the Socket directly (BeginReceive/EndReceive), or you can use a NetworkStream (BeginRead/EndRead).  At the end of the day, it's just a matter of semantics.  I have GPL code available here that does this; in fact, it is intended to be used in a way that you override this class and simply override OnDataReceived() and OnDataSent(), and that you provide your own Send() method but call OnDataSending() to actually send the data.
I have a programming folder, and I have nothing of value there

Running with Code has a new home!

Our species really annoys me.

Offline GameSnake

  • News hound
  • Hero Member
  • *****
  • Posts: 2937
    • View Profile
Re: [C] Help with socket connections
« Reply #7 on: August 25, 2005, 03:21:34 pm »
Thanks MyndFyre issue resovled!