Eli olen tekemässä ohjelmaa VB6:lla, jolla näkee tiedot joltakin America's Army -pelin serveriltä. Olen jo tehnyt testinä tietojen hausta PHP-sivun (PHP:tä osaan paremmin), joka toimii moitteetta (http://koti.mbnet.fi/roinaa/aa.php?ip=213.228.
Kun taas VB 6.0:lla tehdyllä ohjelmallani käytän samaa tapaa saadakseni tiedot, serveri ei lähetäkään mitään tietoa / en näe sitä. Protokollana on UDP PHP:ssä ja VB:ssä. Tiedot haen serveriltä näillä merkkijonoilla:
- PHP: "\xFE\xFD\x00"."AASF"."\xFF\xFF\xFF"
- VB: (Chr(254) & Chr(253) & "AASF" & Chr(255) & Chr(255) & Chr(255))
Molempien merkkijonojen lopputulosten pitäisi vastata toisiaan, mutta vastausta ei näy VB:llä. Testinä kokeilin vaihtaa portin 1716:een, jolloin http://koti.mbnet.fi/roinaa/aa.php?ip=213.228.
Miksi siis en saa / näe mitään tietoa serveriltä, kun portti on oikea (voiko serverin lähettämä jono olla liian pitkä, tms?)
Tässä pätkä, joka vastaanottaa serverin lähettämät tiedot, ja lisää ne Testi-nimiseen textboxiin:
Private Sub Winsock_DataArrival(ByVal bytesTotal As Long) Dim strData As String ' Haetaan data socketista Winsock.GetData strData ' Näytetään tieto textboxissa Testi.Text = Testi.Text & vbCrLf & strData ' Rullataan scrollbarit alas Testi.SelStart = Len(Testi.Text) End Sub
Ohjelman voi ladata täältä: http://koti.mbnet.fi/roinaa/AAServerInfo.exe, voit myös tarvita tätä: http://koti.mbnet.fi/roinaa/MSWINSCK.OCX.
Ainakin semmoinen ero merkkijonoissasi on, että PHP:ssä on mukana nollatavu (\x00), mutta VB:ssä sitä ei ole (Chr(0)).
No niinpäs olikin jäänyt tuo nollatavu pois. Lisäsin sen merkkijonoon, eli
Winsock.SendData (Chr(254) & Chr(253) & Chr(0) & "AASF" & Chr(255) & Chr(255) & Chr(255))
mutta sama tulos; väärällä portilla saan lyhyen merkkijonon ("@ÿ>"), oikealla en mitään. Mikähän tuossa nyt oikein mättää?
EDIT:
' Lähetetään kysely Dim kysely As String kysely = (Chr(254) & Chr(253) & Chr(0) & "AASF" & Chr(255) & Chr(255) & Chr(255)) Winsock.SendData kysely MsgBox (kysely)
Muokkasin kyselyn lähettämisen tuollaiseksi. Minkä takia msgboxiin tuleekin vain kaksi ensimmäistä merkkiä, eikä nollatavun jälkeen mitään? Voisiko olla, että sockettikaan ei lähetä kuin kaksi ensimmäistä kirjainta?
Kokeilin nimittäin lähettää serverille vain (Chr(254) & Chr(253) väärään porttiin, ja saan silloin saman tuloksen, kuin "oikeallakin" merkkijonolla, eli "@ÿ>".
Chr(0) aiheuttaa näemmä sen, että merkkijono katkaistaan Chr(0) kohdalta, joten tuota tapaa ei voi käyttää. Eli miten tuon saman kyselyn voisi lähettää tavuina, eikä merkkijonona?
Jaah Bagard huomasikin jo tämän mutta silti:
Public Class Form1 Dim kysely As String = (Chr(254) & Chr(253) & Chr(0) & "AASF" & Chr(255) & Chr(255) & Chr(255)) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load TextBox1.Text = kysely End Sub End Class
Minulla tämä koodi näyttää TextBox1:ssä tekstin "þý". Kun Chr(0):n korvaa Chr(1) näkyy teksti "þý�AASFÿÿÿ" jossa lisäksi on ý:n ja A:n välillä laatikko jota ei tuossa näy.
Jep, eli miten saisin lähetettyä tuon merkkijonon serverille ilman, että VB katkaisee sitä? Pitäisikö se lähettää tavuina? Jos, niin miten tuo käytännössä tapahtuu?
Luo byte array ja lähetä se.
Dim ByteArray() As Byte ' muuta string ANSI-muotoon ja sitten tavuiksi ByteArray = StrConv((ChrW$(254) & ChrW$(253) & _ ChrW$(0) & "AASF" & ChrW$(255) & ChrW$(255) & _ ChrW$(255), vbFromUnicode) Winsock.SendData ByteArray
Voi sitten olla että tuokaan ei vielä lähetä dataa eteenpäin, en ole varma kun en ole Winsockilla lähettänyt raakaa dataa. Winsock yleensä vaatii sen, että rivin loppuun lisätään vbCrLf että data lähtee matkaan eikä jää paikalliseen bufferiin lojumaan. Mutta tämä siis tekstimuotoisen datan kanssa, raakadata voi olla eri juttu.
Eipä vieläkään toimi, eli nyt data lähetetään ja vastaanotetaan näin:
Private Sub HaeTiedot_Click() ' Tuhotaan vanha socketti Winsock.Close ' Yhdistetään socketti Winsock.RemoteHost = IP.Text Winsock.RemotePort = Portti.Text Winsock.Connect DoEvents ' Lähetetään kysely Dim ByteArray() As Byte ByteArray = StrConv((ChrW$(254) & ChrW$(253) & ChrW$(0) & "AASF" & ChrW$(255) & ChrW$(255) & ChrW$(255)), vbFromUnicode) Winsock.SendData ByteArray DoEvents MsgBox ByteArray End Sub Private Sub Winsock_DataArrival(ByVal bytesTotal As Long) Dim strData As String ' Haetaan data socketista Winsock.GetData strData ' Näytetään data textboxissa Testi.Text = Testi.Text & vbCrLf & strData ' Rullataan scrollbarit alas Testi.SelStart = Len(Testi.Text) End Sub
Koklaa huviks vaik jotenki tällee kans (emt onks tos typoja tms, kirjotin suoraa hatusta tähän tekstilootaan):
Dim tavut() As Byte Dim i As Integer tavut = Array(254, 253, 0, Asc("A"), Asc("A"), Asc("S"), Asc("F"), 255, 255, 255) For i = 0 To 9 Winsock.SendData tavut(i) Next
Emt sitte, eroaaks toi tosta, mitä nyt käytät, ollenkaa. Muista myös, että jos serveriltä saadaan nollatavu, se poikkasee tekstilootan. Eli, jos koitat laittaa vaik tekstilootaan tekstin "foo" & Chr$(0) & "bar", niin siinä näkyy sitte vaan foo. Mää näyttäsin ton sekä tekstinä, että vaikka heksana myös.
Voisit kokeilla sellaista, että laitat PHP-skriptin lähettämään merkkijononsa VB-ohjelmalle ja sieltä sitten katsot, mitä tuli perille. (Suosittelen tuota taulukkoa.) Saat ainakin selville, onko jotakin eroa.
soodan koodi valittaa "Type mismatch", kun yrittää lähettää. Ja mitäs tuo auttaa, että näen mitä tuo PHP-skripti lähettää, kyllähän jo tiedän tarkalleen mitä serverille pitää lähettää että tiedot saadaan. Ongelmanahan on nollatavun lähetys muun tiedon mukana.
Höh-häh, eiks winsockilla muka voi lähettää byteä? o_O
Debugin mukaan vika on tällä rivillä:
tavut = Array(254, 253, 0, Asc("A"), Asc("A"), Asc("S"), Asc("F"), 255, 255, 255)
Jonku aikaa siitäki ku vb:llä viimeks koodailin, koklaa sitte jotain tämmöstä:
Dim i As Integer Dim tavu As Byte tavut = Array(254, 253, 0, Asc("A"), Asc("A"), Asc("S"), Asc("F"), 255, 255, 255) For i = 0 To 9 tavu = tavut(i) Winsock.SendData tavu Next
Ei enää valita mistään, mutta eipä tuo serverikään mitään vastaile.
Ongelma ratkaistu, eli winsockilla kyllä saa ihan rauhassa lähetellä nollatavuja. Ongelma oli siinä, että serverin vastauksen ensimmäinen kirjain oli myös nollatavu, jolloin en nähnyt vastausta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.