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.
Related
I am new in socket programming. I have a client application written in c++ that connect to camera. And then Camera sends the packet of frames in chunks between 0 - 1460. I have used recv function to receive the packet. I saw soo many question in which it was clearly mentionthat recv function return the bytes received, but in my case recv function returning the value written in the 3rd parameter of the recv function i.e len. So is their anyway through whichI can find the actual bytes received.
I even try to use char* but that not even work.
So, anyone please tell me the solution.Any help will be appreciable. Thank in Advance
char *buf = new char[1461];
int bytes = recv(sock, buf, 2000, 0);
printf("%d", bytes);
that always print 2000.
because of that after the valid bytes in the buf their are unknown bytes that's results in unexpected Image.
First of all, your code has a bug (which leads to undefined behavior).
You have allocated 1461 bytes but you are trying to read more than that:
It should go like this:
vector<char> buf(5000); // you are using C++ not C
int bytes = recv(sock, buf.data(), buf.size(), 0);
std::cout << bytes;
Secondly result is as expected. Camera sends much more data than 2000 bytes, so I'm not surprised that number of bytes read covers whole requested size.
This is more of a request for confirmation than a question, so I'll keep it brief. (I am away from my PC and so can't simply implement this solution to test).
I'm writing a program to send an image file taken via webcam (along with meta data) from a raspberryPi to my PC.
I've worked out that the image is roughly around 130kb, the packet header is 12b and the associated meta data another 24b. Though I may increase the image size in future, once I have a working prototype.
At the moment I am not able to retrieve this whole packet successfully as, after sending it to the PC I only ever get approx 64kb recv'd in the buffer.
I have assumed that this is because for whatever reason the default buffer size for a socket declared like:
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);
is 64kb (please could someone clarify this if you're 'in the know')
So - to fix this problem I intend to increase the socket size to 1024kb via the setsockopt(x..) command.
Please could someone confirm that my diagnosis of the problem, and proposed solution are correct?
I ask this question as I am away form my PC right now and am unable to try it until I get back home.
This most likely has nothing to do with the socket buffers, but with the fact that recv() and send() do not have to receive and send all the data you want. Check the return value of those function calls, it indicates how many bytes have actually been sent and received.
The best way to deal with "short" reads/writes is to put them in a loop, like so:
char *buf; // pointer to your data
size_t len; // length of your data
int fd; // the socket filedescriptor
size_t offset = 0;
ssize_t result;
while (offset < len) {
result = send(fd, buf + offset, len - offset, 0);
if (result < 0) {
// Deal with errors here
}
offset += result;
}
Use a similar construction for receiving data. Note that one possible error condition is that the function call was interrupted (errno = EAGAIN or EWOULDBLOCK), in that case you should retry the send command, in all other cases you should exit the loop.
Currently, I'm learning how to build a transparent HTTP proxy in C++. There had two issues on the proxy client side I couldn't resolve for long time. Hope someone can point out the root causes based on following scenarios. Thanks a lot. :D
The HTTP proxy I built right now is somehow work partially only. For example, I could access google's main page through proxy while I couldn't get any search result after I typed keyword(the google instant is also not working at all). On the other hand, youtube is working perfectly includes searching, loading video and commenting. What's more, there also got some websites like yahoo even couldn't display main page after I keyed in its URL.
The reason why I said the issues are on the proxy client side at the begining is because I traced the data flow of my program. I found out the written size returned by socket programming function write() was smaller than the data size I passed to my write back function. The most weird observation for me was the data losing issue is independent from the size of data. The socket write() function could work properly for youtube video data which is nearly 2MB while it would loss data for google search request which is just 20KB.
Furthermore, there also had another situation that browser displayed blank when the data size I passed to my write back function and the written size returned by socket write function() are the same. I used wireshark to trace the flow of communication and compared mine with pure IP communication without proxy involved. I found out that browser didn't continuously send out HTTP requests after it received certain HTTP responses comparing with pure IP communication flow. I couldn't find out why the browser didn't send out rest of HTTP requests.
Following is my code for write back function:
void Proxy::get_data(char* buffer, size_t length)
{
cout<<"Length:"<<length<<endl;
int connfd;
size_t ret;
// get connfd from buffer
memset(&connfd, 0, sizeof(int));
memcpy(&connfd, buffer, sizeof(int));
cout<<"Get Connection FD:"<<connfd<<endl;
// get receive data size
size_t rData_length = length-sizeof(int);
cout<<"Data Size:"<<rData_length<<endl;
// create receive buffer
char* rBuf = new char[rData_length];
// allocate memory to receive buffer
memset(rBuf, 0, rData_length);
// copy data to buffer
memcpy(rBuf, buffer+sizeof(int), rData_length);
ret = write(connfd, rBuf, rData_length);
if(ret < 0)
{
cout<< "received data failed"<< endl;
close(connfd);
delete[] rBuf;
exit(1);
}
else
{
printf("Write Data[%d] to Socket\n", ret);
}
close(connfd);
delete[] rBuf;
}
May be you could try this
int curr = 0;
while( curr < rData_length ) {
ret = write( connfd, rBuf + curr, rData_length - curr );
if( ret == -1 ) { /* ERROR */ }
else
curr += ret;
}
instead of
ret = write(connfd, rBuf, rData_length);
In general, the number of bytes written by write() could differ from what you ask to write. You should better read some manual. Say, http://linux.die.net/man/2/write
Copying bytes between an input socket and an output socket is much simpler than this. You don't need to dynamically allocate buffers according to how much data was read by the last read. You just need to read into a char[] array and write from that array to the target, taking due account of the length value returned by the read.
I am using read function to read data from a socket, but when the data is more than 4k, read function just read part of the data, for example, less than 4k. Here is the key code:
mSockFD = socket(AF_INET, SOCK_STREAM, 0);
if (connect(mSockFD, (const sockaddr*)(&mSockAdd), sizeof(mSockAdd)) < 0)
{
cerr << "Error connecting in Crawl" << endl;
perror("");
return false;
}
n = write(mSockFD, httpReq.c_str(), httpReq.length());
bzero(mBuffer, BUFSIZE);
n = read(mSockFD, mBuffer, BUFSIZE);
Note than BUFSIZE is much larger than 4k.
When data is just a few hundred bytes, read function works as expected.
This is by design and to be expected.
The short answer to your question is you should continue calling "read" until you get all the data you expect. That is:
int total_bytes = 0;
int expected = BUFSIZE;
int bytes_read;
char *buffer = malloc(BUFSIZE+1); // +1 for null at the end
while (total_bytes < expected)
{
int bytes_read = read(mSockFD, buffer+total_bytes, BUFSIZE-total_bytes);
if (bytes_read <= 0)
break;
total_bytes += bytes_read;
}
buffer[total_bytes] = 0; // null terminate - good for debugging as a string
From my experience, one of the biggest misconceptions (resulting in bugs) that you'll receive as much data as you ask for. I've seen shipping code in real products written with the expectation that sockets work this way (and no one certain as to why it doesn't work reliably).
When the other side sends N bytes, you might get lucky and receive it all at once. But you should plan for receiving N bytes spread out across multiple recv calls. With the exception of a real network error, you'll eventually get all N bytes. Segmentation, fragmentation, TCP window size, MTU, and the socket layer's data chunking scheme are the reasons for all of this. When partial data is received, the TCP layer doesn't know about how much more is yet to come. It just passes what it has up to the app. It's up to the app to decide if it got enough.
Likewise, "send" calls can get conglomerated into the same packet together.
There may be ioctls and such that will make a socket block until all the expected data is received. But I don't know of any off hand.
Also, don't use read and write for sockets. Use recv and send.
Read this book. It will change your life with regards to sockets and TCP:
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.