Thread: Received data conversion

  1. #1
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532

    Received data conversion

    I made two applications, a "server" and a "client". The server opens, binds, connects, and listens on a port for connections. It accepts connections and receives data and displays the received data. My other program connects to the other program and sends a buffer initiated as so: "char buffer[256]". That contains a message such as "Hello" or whatever I want to send. The server program receives this and displays it. When it's displayed its just numbers, which is what it's supposed to be because the numbers are what gets sent over the network/internet. I was wondering if there is some kind of macro or function that converts those numbers back to the string it was originally. Thanks.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  2. #2
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    You are sending bytes so all it matters is how you interpret them. Without code it is difficult to tell really what you are doing wrong.

  3. #3
    Registered User
    Join Date
    Apr 2005
    Posts
    134
    How are you seeing it as numbers ? If you send a string and receive as a string, you should be able to display it as a string.

    Infact if you send a buffer which contains a strcture and receive at the other end a buffer which when you cast it to the source structure, should show you all the contents of the structure.

    check this thread

  4. #4
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    Be sure to read the fine print that says that is only true under very specific circumstances.

  5. #5
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Here's the FULL code for the server:
    Code:
    #include <windows.h>
    #include <winsock.h>
    #include <stdio.h>
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    WORD sockVersion;
    WSAData wsaData;
    int nret;
    sockVersion=MAKEWORD(1,1);
    WSAStartup(sockVersion,&wsaData);
    SOCKET listeningSocket;
    listeningSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listeningSocket==INVALID_SOCKET)
    {
    MessageBox(NULL,"Listening socket invalid.","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    SOCKADDR_IN serverInfo;
    serverInfo.sin_family=AF_INET;
    serverInfo.sin_addr.s_addr=INADDR_ANY;
    serverInfo.sin_port=htons(4567);
    nret=bind(listeningSocket,(LPSOCKADDR)&serverInfo,sizeof(struct sockaddr));
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error binding listening socket to port","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    nret=listen(listeningSocket,2);
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error listening on port 4567","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    SOCKET clientsock;
    clientsock=accept(listeningSocket,NULL,NULL);
    if(clientsock==INVALID_SOCKET)
    {
    MessageBox(NULL,"Error accepting connection through listening socket","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    char buffer[256];
    nret=recv(clientsock,buffer,256,0);
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error receiving data","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    LPTSTR mes;
    wsprintf(mes,"%d",buffer);
    MessageBox(NULL,mes,"Received message",0);
    closesocket(clientsock);
    closesocket(listeningSocket);
    WSACleanup();
    return 0;
    }
    Sorry about the lack of comments, it's a bad habit of mine. What I do is receive the buffer and store it in another buffer the same size. Then format it using wsprintf, so it can be displayed in the MessageBox function. When it is displayed it is a number.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  6. #6
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    Look at the conversion specifier you are passing to wsprintf. Hint: It's not the right one.

  7. #7
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Ok, I got it. I used strcpy(mes,buffer); instead of wsprintf. Now it works perfectly, thanks guys.
    Last edited by jmd15; 08-05-2005 at 02:07 PM. Reason: Figured it out
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  8. #8
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    Why even copy it? Also you have to becareful because there is no gurantee buffer will be null terminated, which is why recv tells you how many bytes it received.

  9. #9
    Registered User
    Join Date
    Sep 2001
    Location
    England
    Posts
    121
    Code:
    LPTSTR mes;
    wsprintf(mes,"%d",buffer);
    This code isn't safe (it isn't as strcpy either). I don't know how much you know about managing memory, but LPTSTR is a TCHAR*, ie. a pointer to a space in memory. When you call wsprintf or strcpy, you're asking it to copy information to that space in memory, but as it is, that could be anywhere, you haven't initialised (reserved) a space for that string.

    One way of doing so would be to use TCHAR mes[256] (stack memory) instead of LPTSTR mes. Another would be to use LPTSTR mes = new TCHAR[256] (heap memory). Either way, you're telling the computer to reserve a space. Without doing so, you could be overwriting anything.

    I might also point out that although there are cases when it'd be handy to copy the buffer to a seperate string, there's no need to do so here. You could miss out the above two lines completely and just pass buffer to MessageBox. Strictly speaking though, you should make sure it's null terminated before doing either. buffer[255]='\0' would do. (EDIT: sorry orbitz, I didn't see your post)

    A third thing, you seem to be switching between wide (2 bytes per character), ansi (1 byte per character) and tchar (variable between 1 or 2 depending on whether UNICODE is defined at compile time). wsprintf deals with TCHARs, but strcpy deals with ansi chars. As long as you don't compile as unicode, there's no difference between TCHAR and char (or CHAR), so there's no danger. It is bad practice though to switch between them, and if this was a larger project it'd make migrating to unicode very difficult.

    If you want me to elaborate on anything feel free to ask. I've rushed over things a bit in this post because I don't know how much you already know. By far the most important point of these is the first, make sure you allocate memory properly or it can cause some difficult to find instabilities and crashes, or (worse) weird behaviour in completely seperate parts of the program.
    Last edited by Robert602; 08-05-2005 at 03:35 PM.

  10. #10
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    How about this code then?:
    Code:
    char buffer[256];
    nret=recv(clientsock,buffer,256,0);
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error receiving data","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    MessageBox(NULL,buffer,"Received message",0);
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  11. #11
    Registered User
    Join Date
    Sep 2001
    Location
    England
    Posts
    121
    That's fine in all apart from that you're still not making sure the buffer is null terminated. If it doesnt have a null character in it somewhere, MessageBox won't know where the string ends and it could over run. It shouldn't happen if all is well, but especially over a network you can't rely on that.

    The simplest way to correct this would be to add the line buffer[255]='\0' ('\0' is the null character) just before calling MessageBox, that will make the last character of the buffer null and ensure MessageBox doesn't over run the buffer.

  12. #12
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Thanks, that's just the problem that arose from experimenting.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  13. #13
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Something weird just happened, ever since I added that null character to buffer, it only displays 5 characters of what I sent to it. Here is the full code for the server now:
    Code:
    #include <windows.h>
    #include <winsock.h>
    #include <stdio.h>
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    WORD sockVersion;
    WSAData wsaData;
    int nret;
    sockVersion=MAKEWORD(1,1);
    WSAStartup(sockVersion,&wsaData);
    SOCKET listeningSocket;
    listeningSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listeningSocket==INVALID_SOCKET)
    {
    MessageBox(NULL,"Listening socket invalid.","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    SOCKADDR_IN serverInfo;
    serverInfo.sin_family=AF_INET;
    serverInfo.sin_addr.s_addr=INADDR_ANY;
    serverInfo.sin_port=htons(4567);
    nret=bind(listeningSocket,(LPSOCKADDR)&serverInfo,sizeof(struct sockaddr));
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error binding listening socket to port","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    nret=listen(listeningSocket,2);
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error listening on port 4567","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    SOCKET clientsock;
    clientsock=accept(listeningSocket,NULL,NULL);
    if(clientsock==INVALID_SOCKET)
    {
    MessageBox(NULL,"Error accepting connection through listening socket","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    char buffer[256];
    nret=recv(clientsock,buffer,strlen(buffer),0);
    if(nret==SOCKET_ERROR)
    {
    MessageBox(NULL,"Error receiving data","Error",MB_ICONERROR);
    WSACleanup();
    return 0;
    }
    buffer[255]='\0';
    MessageBox(NULL,buffer,"Received Message",0);
    closesocket(clientsock);
    closesocket(listeningSocket);
    WSACleanup();
    return 0;
    }
    Last edited by jmd15; 08-05-2005 at 08:43 PM.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

  14. #14
    Registered User
    Join Date
    Apr 2005
    Posts
    134
    I think you need to change

    Code:
    nret=recv(clientsock,buffer,strlen(buffer),0);
    to

    Code:
    nret=recv(clientsock,buffer,sizeof(buffer),0);

  15. #15
    C++ Enthusiast jmd15's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    532
    Thanks, now it works with no problems.
    Trinity: "Neo... nobody has ever done this before."
    Neo: "That's why it's going to work."
    c9915ec6c1f3b876ddf38514adbb94f0

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  2. Bitmasking Problem
    By mike_g in forum C++ Programming
    Replies: 13
    Last Post: 11-08-2007, 12:24 AM
  3. Header File Question(s)
    By AQWst in forum C++ Programming
    Replies: 10
    Last Post: 12-23-2004, 11:31 PM
  4. HUGE fps jump
    By DavidP in forum Game Programming
    Replies: 23
    Last Post: 07-01-2004, 10:36 AM
  5. socket question
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 07-19-2002, 01:54 PM