cancel
Showing results for 
Search instead for 
Did you mean: 

ws2_32.dll to write to a socket

Former Member
0 Kudos

the following is my post from PowerBuilder forum on Sybase, where we all PB lovers got our answers for so long. I thought I will post my entire discussion here as well in case everybody is now connected to SCN. If any one had any experience with this it would be great

As I mentioned I will keep looking myself as well and I did find some answers:

ws2_32.dll in syswow64 folder under window folder is although named ws2_32.dll but it is actually 64 bit app and depending on the windows os i m using the correct version of this dll will be used.

I also found out that only binary data can be written to ports and I will have to convert the string to blob before I send it via sendto method to the socket client will be listening on.

.net does have capability to convert blob to string

despite my answers it would be nice if someone who had some experience with this can also chime in, would be of great help.

I will also post this in scn 

> I have a pb app that will have to communicate with an app

> that is written in .net/c# via socket communication. I am

> using send and sendto methods of ws2_32.dll which is built

> for socket communication. The problem is that send and

> sendto only have option of sending data in blob and not

> ascii string. I do not think that sending a string would

> be possible since there is no method that can do that, at

> least not in this dll. Now i m going to ask a dumb

> question but i have to ask it, does the blob datatype in

> pb only converts the ascii string to binary and that is

> all, and if it does I am pretty sure the app on .net side

> can convert the binary  data bk to string and nothing will

> b lost? is my assumption correct? I am pretty sure .net

> has some class that can take binary and convert to string.

> Just curious why ws2_32.dll does not have method to

> transfer string and only binary? is ascii string transfer

> inefficient is that why? also if I do use this dll

> ws2_32.dll and I am using PB 12.5 build 2511 will I run

> into any 32 bit vs 64 bit issue? I would like to know b4 I

> develop a solution. is there something like 64 bit verison

> of this dll? I am doing my own research as well and i will

> report back

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Javed;

   Yes, you can use a few techniques in .Net C# to get Binary (Blob) data transformed into ASCII text. On example would be to use ... System.Convert.ToBase64String ( ). That should not be a problem for the .NET developer to address. Just make sure that PB uses the same encoding technique as the .NET code is expecting.

 

Regards ... Chris

Former Member
0 Kudos

thank u so much Chris, yes I will make sure to use the same encoding standard when i convert to binary. I will now give it a shot and see what happens

Former Member
0 Kudos

I replied to your post in the NNTP Newsgroup.

PowerBuilder is 32-bit when run on 64-bit Windows and you don't have to worry about it, Windows will make sure it uses the right one. You do have to make sure the other app can handle Unicode strings.

Check out my Winsock example:

http://www.topwizprogramming.com/freecode_winsock.html

Answers (1)

Answers (1)

Former Member
0 Kudos

ws2_32.dll is written in C which does not have a string data type. In C strings are arrays of single characters with a null character at the end.

My winsock object will automatically convert strings to blobs when sending and blobs to string when receiving. You can also tell it whether the string data should be Ansi or Unicode.

Former Member
0 Kudos

Thank you Roland: so it is not bcuz you cannot write a string to a port, it is bcuz the dll i m using was written in a language (C) that does not have string datatype. I had written a program a while back for my x employer that was reading and writing strings to a serial port in C# off course here i m using a socket but the end result is same as I did in serial port so that tells me that I can write ascii strings to ports it is just that this dll does not have this capability. That brings me to my other question is ws2_32.dll my only option to create and send data via socket, is there may be another dll that I can find to use? I do agree that your winsock object will convert string to binary and backward but it is not the powerbuilder object that i ahve to problem with I want to make sure that .net will be able to convert from binary to string and Chris has already answered it lets hope it will work. thanks

Former Member
0 Kudos

Technically you could use the string datatype on the PowerBuilder side as long as the other app and your PB app are both Ansi or both Unicode. The PB app defining the data as blob makes it easier to convert between Unicode/Ansi. My Winsock object is also used in my EmailSMTP example which is far and away my most popular. Email is always Ansi so the Winsock object converts the string data to an Ansi blob. The .Net app on the other end doesn't care how you defined it in PowerBuilder. When your PB app passes the data to the winsock function it is treated as a block of memory (a blob in PB). Then winsock on the receiving computer passes the memory block to the .Net Framework which then presents it as a C# datatype. I am not familiar with C# so I don't know what that is.

Former Member
0 Kudos

OK: I am a bit confused now , r u saying that I can pass string type data to sendto method of this dll ws2_32? how do i do that? I did not see an overloaded method that will accept data to be sent as string datatype as one of the parms for this method. am I missing something here?

Former Member
0 Kudos

I was just talking theoretically. You can define the send function in PowerBuilder so that the buffer is string but that limits you to sending only string data that is Unicode PB10 and higher or Ansi PB9 or older. By defining it as blob, that allows you to send binary data such as image files and it also allows you to send Ansi strings from Unicode versions PowerBuilder.

Using my n_winsock object, it always converts to a blob. You can use the of_SetUnicode function to tell it whether the data should be Unicode or Ansi.The base of_send function accepts a blob and there is an override that accepts a string. It converts it to a blob and calls the blob version of the function.

I think you are over thinking this, making it more complex than it really is. Try my Winsock example, it is pretty simple.

Also, note that sendto is for UDP, send is for TCP.

Former Member
0 Kudos

Roland: Can u pl explain what are diffrneces btw send and sendto function of the ws2_32.dll I know you are using them in your winsock example and it helped a gr8 deal looking at your example but in my case the prog listening on the other end is .net app and I need to tell the .net people if the string i send using one of these methods (send or sendto of ws_32) will they have to convert the data from binary to string or will I be able to just send a string that they will be able to recv without converting. Also in your example you have sendtp;ansi alias does this mean that even though we are sending blob data it will be written as regular string. On top of that now I am not sure if i should use sendto (UDP) or send (TCP) how do i find out?

Former Member
0 Kudos

sendto is for UDP and send is for TCP. UDP broadcasts the data to the whole network and TCP requires the two programs to establish a connection first. Most likely you will be using TCP so send would be the function you would use.

If your PB app sends it as string or blob makes no difference to the receiving program. When your PB app calls the send function, it treats it as a blob containing a string.

socket programming is like sending a letter across country. You put the letter in the mailbox. Then your carrier brings it to the post office. The post office sends it to a distribution center. The distribution center sends it to the recipients post office. That post office delivers it to a mailbox. The recipient then takes it out of the mailbox.

The same thing happens with sockets. Your app calls 'send' and the Winsock library on your computer sends the data to the recipients computer. The Winsock library on the recipients computer receives the data and passes it along to the recipients application. There isn't a direct connection between the two apps. If the data contains a string, it doesn't matter if in PB you defined the send function as blob or string. As long as the recipient knows that it contains a string then it should work fine.

The use of ;ansi means that the function expects the string arguments in Ansi format. When the PowerBuilder runtime sees that clause, it automatically converts the Unicode string in your application to Ansi for the function call.

Former Member
0 Kudos

thanks a lot Roland this really helped a lot, i think at this point the best thing would be to put it to test and see what happens I will surely let you know.

Former Member
0 Kudos

Roland: I posted this in sybase forum as well because for some reason sap.com was down, now that it is back up i m posting it here.

i just basically took pointers from your n_winsock object, I basically have a shorter verison of your object (even the code is the same) but I have made sure that the core of it remains the same. I am using of_connect from your example exactly as it is in ur prog:

lul_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)

values for parms are:

AF_INET = 2,

SOCK_STREAM = 1

IPPROTO_TCP = 6 which is used with IPV4 family which is what i have.

lul_scoket does return a valid scoket and no error is returned, i then have

of_SetBlockingMode(lul_socket, False)
   // attempt to connect on the socket
   ll_rc = connect_ws(lul_socket, lstr_sockaddr, MAXGETSOCKADDRSTRUCT)

lstr_sockaddr struct sin_family and sin_port values are set properly also lstr_hostent struct has correct values as well. As a matter of fact ll_rc (return code from connect_ws) is zero and this means that connection was established succesfully and I do not doubt it because if I provide incorrect port purposelly it ll_rc returns -1

The problem is when i send the data using

uo_socket.of_send(lul_socket,ls_test)

ls_test is a simple string 'it works' and then of_send converts it to blob, although when i run it in debug I do not see any value in local blob var that now contains the string but len and other functions on this blob do return value that shows me that there must be something in blob for example

lblob_data = BlobMid(ablob_data, ll_totbytes + 1, ll_MaxBuffer)
ll_sendlen = Len(lblob_data)
ll_totbytes += ll_sendlen


retuns the number of bytes in the string. however when this line is executed

ll_rc = send(aul_socket, lblob_data, ll_sendlen, 0)

ll_rc returns the same number as number of bytes in string and not -1 which is an error code. so it seems like even send is not resutling in an error but no data is transfered to the receiving prog. As a test to make sure firewalls or some other setting is not causing it I used telnet to connect to the client machine and opened a socket via ip address on the same port I am pssing to this prog and string was transfered to the receiving prog. I even tried to convert the string to blob using:

Blob(as_data,EncodingUTF16LE!)

and

Blob(as_data)

thinking that may be the problem was with the format I was using. With blob(as_data) at least I do not get an error, with Blob(as_data,EncodingUTF16LE!) i do get an error when sending data. I am not sure what else I can do, if any help is offered I would appreciate.

JUR.

arnd_schmidt
Active Contributor
0 Kudos

Try sending an UTF8 or ANSI encoded string.

Blob(as_data,EncodingUTF8!)

or

Blob(as_data,EncodingANSI!)

And yes, PowerBuilder does not show the content of a blob in the debugger.

Former Member
0 Kudos

I just wanted to add for anyone's future help that comments by Roland were abs most helpful and I guess my excessive questions may have caused a little bit of frustration on part of some veterans of PB and this forum and I do appologize for it. I just wanted to share that yes Roland's nonvisual class he has created for socket communication is probably the best I have seen. It works seamlessly. My only problem was that I wanted to use only part of it and did not really need the entire object and in customizing I missed few things. .Net program really did not care what is inside the blob before it was written to the socket, as long as I communicated to the developer who was writing the prog on .net side that I will be sending a string. Binary format does matter but the binary format Roland is using in his object EncodingUTF16! worked fined with the .Net program and I did not have to change it. The problem with my customization was that I was turning off the blocking on the port and then make a connection but never set the blocking on again before sending the data as Roland does in his program. After I set the port blocking to true after making the connection and then send the data and close socket after the send everything worked fine and now it is writing to socket no problem. thanks to all for their help.