SOCKET lhSocket;
int iResult;
lhSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
char *sendbuf = "this is a test";
iResult = send(lhSocket, sendbuf, (int)strlen(sendbuf), 0 );
printf("Bytes Sent: %ld\n", iResult);
I have client and Server program using sockets in C++ now i send a buffer it is received by server now when server acknowledge me back saying i got your packet i should get that in string format not bytes received : something. how to achieve that ?
My iresult returns me an integer value, I am sending a message over socket to server , i dont want to print it as Bytes sent : 14.
I want to print the message sent as string to server.
I am dealing with Sockets.
How i can achieve this in C++
stringstream buf;
buf << 12345;
buf.str(); // string("12345")
buf.str().c_str(); // char* "12345"
sendbuf is the string which you are sending. Print sendbuf instead:
printf("Bytes Sent: %s\n", sendbuf);
Another opportunity is boost::lexical_cast<>
const int myIntValue = 12345;
const std::string myStringValue = boost::lexical_cast(myIntValue);
You're asking different things in the title and your post.
Converting int to string in C++ is done with
#include <sstream>
std::ostringstream oss;
oss << some_int;
// do whatever with oss.str()...
as Tomasz illustrated.
To receive data from a socket, you need to make a further call to either recv() or read(). Your "send" call does not itself wait for the reply. recv() or read() accept character-array buffers to read the response into, but you will need to loop reading however much the calls return until you have enough of a response to process, as TCP is what's called a "byte stream" protocol, which means you are not guaranteed to get a complete packet, line, message or anything other than a byte per call.
Given the level of understanding your question implies, I strongly suggest you have a look at the GNU libC examples of sockets programming - there are some server and client examples - easily found via Google.
if you use visual C++ 2008 or 2010 i think there is a function inbuilt to do your job.
something like itoa(int); will convert the given int and return a char *
pretty simple
its in stdlib.hlbtw
** make sure this is not the same in all compilers or distrubutions
http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/
here is a link for reference
Take a look at itoa which converts an integer to a string.
Related
The output when I send hello.
I'm coding a C++ TCP server and I'm using a while loop to continuously get data but I think it's accepting the same thing and prints a bit of the thing that it's meant to output.
while (true)
{
char buffer[5];
if (recv(clisoc, buffer, sizeof(buffer), 0)) {
string abc = (string)buffer;
cout << abc.substr(0, sizeof(buffer));
}
}
Any help would be appreciated thanks!
You only tested the return value of recv to see if it didn't detect a normal close, so none of your subsequent code has any idea how much data you received. Likely, you are receiving data once but printing it twice. You cannot cast arbitrary data to a string, that is legal only for a pointer to an actual string.
//server side
void* s2(void *arg){
info *s = (info*)arg;
char buffer[MAXS];
int k;
sockaddr_in addr;
socklen_t aSize = sizeof(sockaddr_in);
int sfd = accept(s->fd,(sockaddr*)&addr,(socklen_t*)&aSize);
if(sfd<0){
s->current--;
pthread_exit(0);
}
while(1){
k = recv(sfd,buffer,MAXS,0);
cout<<buffer<<"\n";
//1. k ==0 socket has been closed by client
//2. k==-1 error in recv
//3. recv quit
if((k==-1)||(!strncmp(buffer,"quit",4))||(k==0))break;
sprintf(buffer,"%d\n",(int)strlen(buffer)); //Convert length to string using sprintf()
send(sfd,buffer,strlen(buffer),0); //send buffer to client
}
close(sfd);
if(s->limit==s->current)
FD_SET(s->fd,&sfds);
s->current--; //decreament the client number
pthread_exit(0);
}
//client side
1. send(sockfd,"sadhdag",8,0);
2. send(sockfd,"ss",3,0);
Server recv sadhdag in first call to recv .
In second call to recv server recv
ss
dag
server side:
function s2 is run by a thread and argument is passed with socket information connection is accepted there and send and recv is called onn newly accepted client.
Why this is happening ? or how to avoid this ?
You're ignoring the count returned by recv(). Contrary to suggestions in comments, it isn't necessary to memset() the buffer to zero before recv(), but it is necessary to only use that buffer afterwards up to that count. For example:
printf("%s", buffer);
is wrong, and
printf("%.*s", count, buffer);
is right.
NB
if((k==-1)||(!strncmp(buffer,"quit",4))||(k==0))break;
isn't correct either. It should be
if((k==-1)||(k==0)||(k >= 4 && !strncmp(buffer,"quit",4))) break;
It isn't valid to look into the buffer at all unless k is positive, and it isn't valid to compare four characters in it unless there are four characters in it.
You forgot to actually implement any kind of protocol or application-level logic of any kind. This sums it up:
k = recv(sfd,buffer,MAXS,0);
cout<<buffer<<"\n";
This code suggests you're terminating your messages with a newline:
sprintf(buffer,"%d\n",(int)strlen(buffer)); //Convert length to string using sprintf()
send(sfd,buffer,strlen(buffer),0); //send buffer to client
If so, where's the code to parse that on the other end? You throw the returned length away, so you wouldn't even know which characters to check for a newline.
TCP is a byte-stream protocol that does not preserve application-level message boundaries. If you want to use it to send strings or other application-level messages, you have to specify and implement an application-level protocol to do it.
You call recv to get the raw TCP data, then you output it as if it was a string. If you're going to define and implement a protocol to send and receive strings over TCP, you have to actually do it. You can't just imagine it happens by magic.
If you want to receive newline-terminated messages into C-style strings, you can certainly do it. But you have to actually write the code to do it.
I am sending the server a message.
For example: "Hello World."
I want the server to send back the message: "hello world."
for(;;) //listen forever
{
ClntLen = sizeof(ClntAddr);
NewSockfd = Accept(Sockfd, (sockaddr*)&ClntAddr, &ClntLen);
//Read message
read(NewSockfd, Buff, MAX_SIZE);
//convert to lower, send back to client
write(NewSockfd, Buff, MAX_SIZE);
close(NewSockfd);
}
I have tried using tolower(), but in a server I just can't get it right without giving me errors.
Summary: Read Buff (char array), convert it to lowercase, Write it back to the client.
Please explain how its done.
Thanks in advance.
Show us your code to call tolower, please
When you call read, you should get its return value as the actual data returned from socket and then call tolower to convert them to lowercase and then send this buffer back with the length it returned from read.
I am having trouble with a Winsock2 wrapper classes (client-server) and after countless hours of scratching-my-head-in-confusion, I decided it would be better if I asked your opinion.
To be more specific, the problem is that every time I use my Send() function, both the client and the server (not always!) send one or two extra bytes!
For example I use SendBytes("Hello") and the Recv function returns "Hello•" with a '•' or other random characters at the end of the character array.
//main.cpp (Client)
#include "Socket.h"
int main()
{
NetworkService::Client cService = NetworkService::Client();
int res = cService.Initialize("127.0.0.1","20248");
if(res == 0){
int local = cService.SendBytes("Hello!");
printf("Bytes Sent: %ld\n", local);
cService.Shutdown();
char* temp = cService.Recv();
printf("String Recieved: %s - Size: %d",temp,strlen(temp));
printf("\nSTRLEN: %d",strlen("X5"));
}
else{
cService.Clean();
}
cService.Close();
while(!kbhit());
return 0;
}
Of course, the server sends the string "X5" and the client prints the strlens ...
//The result with "X5" as the dummy text:
String Recieved: X5? - Size: 3 //Notice the extra '?' character
STRLEN: 2
Send // Recieve Functions
int NetworkService::Client::SendBytes(char* lData){
int local = send( ConnectSocket, lData, (int)strlen(lData), 0 );
if (local == SOCKET_ERROR) {
Close();
return WSAGetLastError();
}
return local;
}
char* NetworkService::Client::Recv(){
recv(ConnectSocket, recvbuf , recvbuflen, 0);
return recvbuf;
}
Help would be appreciated ^_^.
Excuse me, but
int local;
(...)
return (int*)local;
What you were trying to achieve? There are many serious problems in your code.
This is not the way you send data over the network. There are too many errors.
IF you want to send null-terminated strings over the network:
int local = send( ConnectSocket, lData, (int)strlen(lData), 0 );
as everyone said, you don't actually send the null terminator. You would have sent it if you added 1 to the length. Moreover, with long strings, the send() function doesn't guarantee you to send the whole string at once. You have to check for that and resend the missing part.
recv(ConnectSocket, recvbuf , recvbuflen, 0);
You don't check the return value, so you can't know the length of the received string. As you don't send the null byte, the received data is not null-terminated. Also, if null terminator is the only delimiter of more data you send, you'll have to read byte-by-byte (not efficient) not to miss the null terminator to know when to finish. An alternative would be to make your own buffering scheme (so the next read would partially return the result of the previous), or change the protocol to make length of the transported data known beforehand. Also, the same remark about partial reads as with the send function applies here.
BTW returning a static/global buffer is not a sign of good code.
You don't really check the return value of recv.
There is a do-while but it doesn't do anything. You return from the function without proper error handling even when recv fails, but you will never know it.
Also you don't send the terminating \0 which isn't necessary bad, depends on what you're trying to do, for example you can add that after receiving.
I am doing some socket stuff on Symbian, which works fine so far. However,
I am facing a weird problem when trying to read out the data that has been sent.
Assume the code looks as follows:
TSockXfrLength len;
iSocket.RecvOneOrMore( buff, 0, iStatus, len );
User::WaitForRequest(iStatus);
if (iStatus == KErrNone)
{
printf(_L("Bytes received 1st try %4d..."), len);
printf(_L("Bytes Length received 2nd try %4d..."), &len);
}
Output in both cases is something with 7450 although I received exactly 145 bytes.
I can check that with a network analyser. Anyone knows what I am doing wrong here that
I do not get the proper bytes that have been received?
EDIT:
I am connecting to the socket in the following way:
TInetAddr serverAddr;
TUint iPort=445;
TRequestStatus iStatus;
TSockXfrLength len;
TInt res = iSocketSrv.Connect();
res = iSocket.Open(iSocketSrv,KAfInet,KSockStream, KProtocolInetTcp);
serverAddr.SetPort(iPort);
serverAddr.SetAddress(INET_ADDR(192,100,81,54));
iSocket.Connect(serverAddr,iStatus);
User::WaitForRequest(iStatus);
Hope that helps ;)
Thanks
Try
printf(_L("Bytes received 1st try %4d..."), len());
The TSockXfrLength type is actually a typedef of TPckgBuf<TInt>. This is the Symbian Descriptor way of storing arbitrary simple data in a 8-bit descriptor. To retrieve the value from the len object you need to use the () operator.
More information about TPckg* classes are available in the symbian developer library.