-
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.
-
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.
-
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
-
Be sure to read the fine print that says that is only true under very specific circumstances.
-
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.
-
Look at the conversion specifier you are passing to wsprintf. Hint: It's not the right one.
-
Ok, I got it. I used strcpy(mes,buffer); instead of wsprintf. Now it works perfectly, thanks guys.
-
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.
-
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.
-
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);
-
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.
-
Thanks, that's just the problem that arose from experimenting.
-
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;
}
-
I think you need to change
Code:
nret=recv(clientsock,buffer,strlen(buffer),0);
to
Code:
nret=recv(clientsock,buffer,sizeof(buffer),0);
-
Thanks, now it works with no problems.