🔒 Locked
Changing far pointers to pointers?
Advertisement
Original Post
Ok, I'm using WSARecv for an IOCP server, and I am looking at the platform sdk example from feb 2003. Anyway, it is an echo server, but I'd like to parse it so basic commands can be read. The wsabuf is what contains the data, I believe, and it's buf is a far pointer. I tried all things I could think of and I always get an address printed. If someone can help me out about this, thatd be great!
Can we see the code you are using? You can safely ignore the FAR and use a char * (assuming this is C++ or a 32 bit platform).
jfl.
jfl.
Alright, what language are you using, and could you please show some of your code?
C++ in VC++ 6.0:
Here's the struct that contains wsabuf
I dont know what else to show you; the example is over 1600 lines and I did little to no modification.
All I'm trying to do is access the data recieved and the data being sent so I can parse it and handle it accordingly. I appreciate your willingness to help!
Here's the struct that contains wsabuf
typedef struct _PER_IO_CONTEXT{ WSAOVERLAPPED Overlapped; char Buffer[MAX_BUFF_SIZE]; WSABUF wsabuf; int nTotalBytes; int nSentBytes; IO_OPERATION IOOperation; SOCKET SocketAccept; struct _PER_IO_CONTEXT *pIOContextForward;} PER_IO_CONTEXT, *PPER_IO_CONTEXT;I dont know what else to show you; the example is over 1600 lines and I did little to no modification.
All I'm trying to do is access the data recieved and the data being sent so I can parse it and handle it accordingly. I appreciate your willingness to help!
You are using that structure? According to the MSDN, WSARecv() just takes an array of WSABUFs. Those WSABUFs have a buffer and a length. You should probably copy from the buffer into your own char array so that you'll have a null terminated string. Then print that.
Well, it really depends on what you are trying to do with the data. Again, you can safely ignore the far specifier since it's a C-compatibility "feature". I'll give a few examples:
Copy the buffer to a vector:
(or)
Send the buffer to std::cout (creating begin and end pointers this time):
Parse directly (with no regard for endianness):
I don't know. What example are you using?
By the way, Visual C++ 6.0 is out of date. I highly recommend you update to Visual C++ 2005 Express Edition (you would also need the Platform SDK). It's free.
jfl.
Copy the buffer to a vector:
std::vector< char > buffer( wsabuf.buf, wsabuf.buf + wsabuf.len );(or)
std::vector< char > buffer;buffer.resize( wsabuffer.len );std::copy( wsabuf.buf, wsabuf.buf + wsabuf.len, buffer.begin() );Send the buffer to std::cout (creating begin and end pointers this time):
char const * const begin = wsabuf.buf;char const * const end = wsabuf.buf + wsabuf.len;std::copy( begin, end, std::ostream_iterator( std::cout ) );Parse directly (with no regard for endianness):
char const * const begin = wsabuf.buf;char const * const end = wsabuf.buf + wsabuf.len;for( char const * it = begin; it != end; ++it ) { if( 32 == *reinterpret_cast< int * >( it ) ) { std::cout << "We have the number 32. It stands for something." << std::endl; // process data after 32. }}I don't know. What example are you using?
By the way, Visual C++ 6.0 is out of date. I highly recommend you update to Visual C++ 2005 Express Edition (you would also need the Platform SDK). It's free.
jfl.
Quote:
Original post by Colin Jeanne
You are using that structure? According to the MSDN, WSARecv() just takes an array of WSABUFs. Those WSABUFs have a buffer and a length. You should probably copy from the buffer into your own char array so that you'll have a null terminated string. Then print that.
Straight from the MSDN:
int WSARecv( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);Also, I try copying it, and when it prints, it seems to print its ASCII value of the first character only. Im sufre I'm doing something wrong here, but the WSABUF has 2 things, yes, the buf and the len. I copy the buf part, but it usually gives me errors.
for instance:
&jBuf[0] = lpIOContext->wsabuf.buf;wont compile
jBuf[0] = *lpIOContext->wsabuf.buf;prints the ascii.
ive tried several other methods even if I think theyd be wrong, just because I'm out of ideas.
As for VC6.0 being out of date? It gets the job done fine, and I'd rather stick with it for now, thanks for your input though.
When I say out of date, I mean pre-standard. That means that VC6.0 can barely be called a C++ compiler.
As for your code examples:
- The first is trying to assign to the value returned by the address-of operator, which is an rvalue.
- The second only copies the first character in the buffer to your array.
If you want to copy the data in the buffer to your array, then (assuming your array is large enough):
std::copy( wsabuf.buf, wsabuf.buf + wsabuf.len, jBuf );
As for printing ascii, what exactly are you expecting?
jfl.
As for your code examples:
- The first is trying to assign to the value returned by the address-of operator, which is an rvalue.
- The second only copies the first character in the buffer to your array.
If you want to copy the data in the buffer to your array, then (assuming your array is large enough):
std::copy( wsabuf.buf, wsabuf.buf + wsabuf.len, jBuf );
As for printing ascii, what exactly are you expecting?
jfl.
Quote:
Original post by jflanglois
When I say out of date, I mean pre-standard. That means that VC6.0 can barely be called a C++ compiler.
As for your code examples:
- The first is trying to assign to the value returned by the address-of operator, which is an rvalue.
- The second only copies the first character in the buffer to your array.
If you want to copy the data in the buffer to your array, then (assuming your array is large enough):
std::copy( wsabuf.buf, wsabuf.buf + wsabuf.len, jBuf );
As for printing ascii, what exactly are you expecting?
jfl.
Thank you very much, however it does not work =( Well, it might.. what exactly is it supposed to return? I cannot find documentation on it. Right now it seems to be returning a pointer.
if I follow with a print of the array, it prints a pointer, but if I print a *jBuf, it prints the ascii of the first charaxter again.
How can I get it to be copied to a character array so I have it in normal characters.. so if the client sends "hello", the character array is "h", "e", "l", etc which equals "hello". thanks
The std::copy will copy it to another character array, but be aware that wsabuf.buf is itself a character array. How are you trying to print it? Show some code.
You poor thing. You have no understanding of C pointers, null-terminated character arrays abused as strings, and C++'s std::string, do you?
C has a number of standard library routines that will treat a sequence of char elements as though it were a string, with the end of the string being indicated by null (0, '\0'). The problem with this is that you can not assign a C-style null terminated character array using '='. Why? Because C arrays are not first-class objects.
C++ simplifies this for you by providing the std::string type, which provides a special overload of operator= that allows you to treat string literals, std::string objects and null-terminated character arrays on the right-hand side only as though they were first-class objects.
You can thank me later. [smile]
(Oh, yeah. Upgrade. VC++ 6.0 is an anachronism now. Plus, VC++ 8 Express is free!)
char *c = "Hello";c is a pointer. c is not a string. c points to the first element of the array of characters, {'H', 'e', 'l', 'l', 'o', '\0'}. Consequently, dereferencing c will give you the first element in that sequence, 'H'.C has a number of standard library routines that will treat a sequence of char elements as though it were a string, with the end of the string being indicated by null (0, '\0'). The problem with this is that you can not assign a C-style null terminated character array using '='. Why? Because C arrays are not first-class objects.
C++ simplifies this for you by providing the std::string type, which provides a special overload of operator= that allows you to treat string literals, std::string objects and null-terminated character arrays on the right-hand side only as though they were first-class objects.
std::string s = c; // workss = "Something else"; // workss = wsabuf.buf; // worksYou can thank me later. [smile]
(Oh, yeah. Upgrade. VC++ 6.0 is an anachronism now. Plus, VC++ 8 Express is free!)
Thank you very much, all of you, but the last post was especially helpful. I wouldnt say I have no understanding, but everything I know is self taught, and somethings I know well, and some I dont have a slighest clue. I'm enrolled in some classes for college and I'll be starting soon, but so far, online tutorials, a book or two, and nice people like you guys have been my saviors :D
Anyway, thanks again, and I'm sorry if my lack of knowledge is astonishing =(
Anyway, thanks again, and I'm sorry if my lack of knowledge is astonishing =(
Quote:
Original post by Oluseyi
s = wsabuf.buf; // works
Ehe, no. It doesn't. WSABUF::buf is not null-terminated, which is why WSABUF::len exists. You can use string::assign(), though:
std::string s;
s.assign( wsabuf.buf, wsabuf.len );
This is all the more reason to use std::string where possible, though.
As an aside, I would use std::vector< char > for buffers, if only to express intent.
jfl.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement