Read() function doesnt read the entire data on serial communication - c

Here is my code
void Reading_TtyS0()
{
int ret;
char mypipe_ttyS0[80] = {0};
fcntl(fd, F_SETFL, 0);
ret = read(fd, ttyS0_mypipe , 80 );
printf(ret = %d\n", ret);
if (ret > 0)
{
perror("Message Log, Reading /dev/ttyS0");
printf("Message Log, Reading /dev/ttyS0 with data = %s\n", ttyS0_mypipe);
tcflush(fd, TCIFLUSH);
ret = 0;
}
}
My output is
ret = 8
Message Log, Reading /dev/ttyS0: Success
Message Log, Reading /dev/ttyS0 with data = 0066923:
I am reading only 8 bytes instead of 80.
I should receive 0066923:12:13:134:1134:112344:333...(till 80 bytes)
The output on gtkterm and I am receiving the complete data.

read() does not necessarily return the number of bytes it was told to read.
So loop around read until you got what you want:
char mypipe_ttyS0[80] = {0};
fcntl(fd, F_SETFL, 0);
size_t bytes_to_read = 80;
size_t bytes_read = 0;
while (bytes_to_read > 0)
{
ssize_t result = read(fd, ttyS0_mypipe + bytes_read, bytes_to_read);
if (-1 == result)
{
if ((EWOULDBLOCK == errno) || (EAGAIN == errno))
{
continue;
}
perror("read() failed");
break;
}
else (0 == result)
{
fprintf(stderr, "Connection closed.");
break;
}
printf("Read %zd bytes.\n", result);
bytes_to_read -= result;
bytes_read += result;
}
....

Its non-blocking read operation, so its possible that read will return whatever data received in the buffer at the moment.
You have to loop through the read until all data received.
int ret;
char mypipe_ttyS0[80] = {0};
fcntl(fd, F_SETFL, 0);
int i = 5; // let say iterate 5 times
int bytes_to_read = 80;
ret = 0;
while (i > 0)
{
ret += read(fd, mypipe_ttyS0 + ret , bytes_to_read );
printf(ret = %d\n", ret);
bytes_to_read -= ret;
if(bytes_to_read == 0)
{
break;
}
++i;
}
if (bytes_to_read == 0)
{
perror("Message Log, Reading /dev/ttyS0");
printf("Message Log, Reading /dev/ttyS0 with data = %s\n", ttyS0_mypipe);
tcflush(fd, TCIFLUSH);
ret = 0;
}

Related

tcp server blocking read in C

I want to implement a simple TCP server with blocking read, that receives messages sent from a client character by character until a separator. Once a message is received, it has to wait until the next message appears. Here is my pseudocode:
// Messages sent from the client
char *message1 = "mssg1\n"
char *message2 = "mssg2\n"
// On server side
char buffer;
char completeMessage[5]
while(1){
while(buffer != '\n'){
recv(sock, &buffer, 1, 0); // 1 is the read size
if(buffer != '\n') {
printf("buffer: %c\n", buffer);
completeMessage[n] = buffer;
count ++;
}
else{
printf("Complete message: %s\n", completeMessage);
count = 0;
}
}
}
And the result is the following:
buffer: m
buffer: s
buffer: s
buffer: g
buffer: 1
Complete message: mssg1
buffer:
buffer:
buffer:
buffer:
buffer:
buffer:
// Error due to buffer overflow
I don't know why recv instead of waiting for the next message character (blocking read), it continues reading blank spaces. My questions are the following:
Is recv really a socket blocking read function?
Is there something wrong or missing in the code?
Any other suggestions for implementing this?
Is recv really a socket blocking read function?
Yes, unless you made the handle non-blocking.
Is there something wrong or missing in the code?,
You're not checking what recv returns. 0 indicates EOF, and -1 indicates an error.
You don't check how full your buffer is, so you risk buffer overflows.
You're not terminating the string in completeMessage with a NUL as required by printf %s.
Any other suggestions for implementing this?
You shouldn't read a character at a time!
#define BUFFER_SIZE (64*1024)
char* extract_string(const char* start, const char* end) {
size_t len = end - start;
char* dst = malloc(len+1);
if (dst == NULL)
return NULL;
memcpy(dst, src, len);
dst[len] = '\0';
return dst;
}
{
char buf_start[BUFFER_SIZE];
char* buf_end = buf_start + BUFFER_SIZE;
char* window_start = buf_start;
char* window_end = buf_start;
while (1) {
if (window_end == buf_end) { // No more space.
fprintf(stderr, "Overly large message");
return 0;
}
ssize_t rv = recv(sock, window_end, buf_end-window_end, 0);
if (rv == -1) { // Error.
perror("recv");
return 0;
}
if (rv == 0) { // EOF.
return 1;
}
while (rv--) {
if (*(window_end++) == '\n') {
char* msg = extract_string(window_start, window_end-1); // Excl LF.
if (msg == NULL) {
fprintf(stderr, "Out of memory");
return 0;
}
// Do something with msg
printf("Complete message: %s\n", msg);
free(msg);
window_start = window_end;
}
}
memmove(buf_start, window_start, window_end-window_start);
window_end -= (window_start - buf_start);
window_start = buf_start;
}
}
There are quite a number of problems with your code, namely that you are ignoring the return value of recv(), you are not null-terminating your buffer before printing it, and you are not protecting yourself from a buffer overflow.
Try something more like this instead:
char ch, *tmp, *message = NULL;
int ret, length = 0, allocated = 0;
while (1)
{
ret = recv(sock, &ch, 1, 0);
if (ret <= 0)
{
if (ret < 0)
printf("Read error: %d\n", errno); // or WSAGetLastError() on Windows
else
printf("Client disconnected\n");
break;
}
if (ch == '\n')
{
if ((length > 0) && (message[length-1] == '\r'))
--length;
printf("Complete message: '%.*s'\n", length, message);
length = 0;
}
else
{
printf("ch: %c\n", ch);
if (length == allocated)
{
if (length >= 5000) // some max length of your choosing...
{
printf("Message length too large!\n");
break;
}
// just for example. You should use a more robust growth algorithm in production code...
tmp = (char*) realloc(message, allocated + 10);
if (!tmp)
{
printf("Memory allocation failed\n");
break;
}
message = tmp;
allocated += 10;
}
message[length] = ch;
++length;
}
}
free(message);
Alternatively, don't read char-by-char. Read as much data as you can from the socket on any given read and store it all in a growing buffer, and then scan that buffer for complete messages, eg:
char *buffer = (char*) malloc(100);
if (!buffer)
{
printf("Memory allocation failed\n");
}
else
{
int ret, offset, remaining, inbuf = 0, allocated = 100;
char *ptr;
while (1)
{
if (inbuf == allocated)
{
if (inbuf >= 5000) // some max length of your choosing...
{
printf("Buffer length too large!\n");
break;
}
// just for example. You should use a more robust growth algorithm in production code...
tmp = (char*) realloc(buffer, allocated + 100);
if (!tmp)
{
printf("Memory allocation failed\n");
break;
}
buffer = tmp;
allocated += 100;
}
ret = recv(sock, buffer+inbuf, allocated-inbuf, 0);
if (ret <= 0)
{
if (ret < 0)
printf("Read error: %d\n", errno); // or WSAGetLastError() on Windows
else
printf("Client disconnected\n");
break;
}
printf("Received: %.*s\n", ret, buffer+inbuf);
inbuf += ret;
while (ptr = (char*)memchr(buffer, '\n', inbuf))
{
offset = (ptr-buffer);
if ((offset > 0) && (buffer[offset-1] == '\r'))
--offset;
printf("Complete message: '%.s'\n", offset, buffer);
++ptr;
remaining = (inbuf - (ptr - buffer));
if (remaining > 0)
memmove(buffer, ptr, remaining);
inbuf = remaining;
}
}
free(buffer);
}

In c socket, why my server can't receive the whole content?

I am new in this field, and writing one server and client, but it really confusing that I can't get all the content, but some small clip.
My server code:
read(connfd, name, 20);
//recv(connfd,name,1024,0);
char* a=name;
while(a[0]!='\n'){
a++;
}
a[0]='\0';
printf("name:%s\n", name);
read(connfd, size, 20);
printf("size:%s\n", size);
recv(connfd,buf,8192,0);
printf("buf:%s\n", buf);
if((stream = fopen(name,"w+t"))==NULL){
printf("The file was not opened! \n");
}
int write_length = fwrite(buf,sizeof(char),8192,stream);
bzero(buf,8192);
if(put){
char *res="OK\n";
write(connfd, res, 1024);
}
fclose(stream);
and my client code is:
char buffer[8192];
bzero(buffer,8192);
char * put="PUT\n";
if ((write(fd, put, 8192)) <= 0) {
if (errno != EINTR) {
fprintf(stderr, "Write error: %s\n", strerror(errno));
exit(0);
}
}
struct stat st ;
stat( put_name, &st );
char str[100];
sprintf(str, "%d", st.st_size);
int len;
char *current=NULL;
len=strlen(put_name);
char sendname[1024];
strcpy(sendname,put_name);
strcat(sendname,"\n");
write(fd, sendname, 10);
strcat(str,"\n");
write(fd, str, 10);
FILE *stream;
if((stream = fopen(put_name,"r"))==NULL)
{
printf("The file was not opened! \n");
exit(1);
}
int lengsize = 0;
while((lengsize = fread(buffer,1,8192,stream)) > 0){
if(send(fd,buffer,8192,0)<0){
printf("Send File is Failed\n");
break;
}
bzero(buffer, 8192);
}
Now, I can send all content, but can receive part of them. for example, on my mac, server can receive name but the str is neglected, when I printf the str in the server, it shows the content of file. and the content of file is not the whole file content. Some content disappear. Could you tell me why?
The read and write functions are not guaranteed to send or receive the entire message with a single call. Instead, you're expected to sit in a loop, writing the message incrementally until everything has been sent and reading everything incrementally until everything has been read. For example, if you know exactly how much has been sent, you can do this:
char recvBuffer[BUFFER_SIZE];
int bytesRead = 0;
while (bytesRead < BUFFER_SIZE) {
int readThisTime = read(file, recvBuffer + bytesRead, BUFFER_SIZE - bytesRead);
if (readThisTime == -1) {
// handle error...
}
bytesRead += readThisTime;
}
If you don't know exactly how much has been sent, try this:
char recvBuffer[BUFFER_SIZE];
int bytesRead = 0;
while (bytesRead < BUFFER_SIZE) {
int readThisTime = read(file, recvBuffer + bytesRead, BUFFER_SIZE - bytesRead);
if (readThisTime == -1) {
// handle error...
}
if (readThisTime == 0) break; // Done!
bytesRead += readThisTime;
}
You are ignoring the return values of send() and recv(). You MUST check return values!
When sending the file, lengsize receives how many bytes were actually read from the file. Your client is sending too many bytes when lengsize is < 8192 (typically the last block of the file if the file size is not an even multiple of 8192).
But more importantly, although the client is telling the server the file size, the server is ignoring it to know when to stop reading. The server is also ignoring the return value of recv() to know how many bytes were actually received so it knows how many bytes can safely be written to the output file.
Try something more like this instead:
common:
int readData(int s, void *buf, int buflen)
{
int total = 0;
char *pbuf = (char*) buf;
while (buflen > 0) {
int numread = recv(s, pbuf, buflen, 0);
if (numread <= 0) return numread;
pbuf += numread;
buflen -= numread;
total += numread;
}
return total;
}
int sendData(int s, void *buf, int buflen)
{
int total = 0;
char *pbuf = (char*) buf;
while (buflen > 0) {
int numsent = send(s, pbuf, buflen, 0);
if (numsent <= 0) return numsent;
pbuf += numsent;
buflen -= numsent;
total += numsent;
}
return total;
}
int readInt32(int s, int32_t *value)
{
int res = readData(s, value, sizeof(*value));
if (res > 0) *value = ntohl(*value);
return res;
}
int sendInt32(int s, int32_t value)
{
value = htonl(value);
return sendData(s, &value, sizeof(value));
}
char* readStr(int s)
{
int32_t size;
if (readInt32(s, &size) <= 0)
return NULL;
char *str = malloc(size+1);
if (!str)
return NULL;
if (readData(s, str, size) <= 0) {
free(str);
return NULL;
}
str[size] = '\0';
return str;
}
int sendStr(int s, const char *str)
{
int len = strlen(str);
int res = sendInt32(s, len);
if (res > 0)
res = sendData(s, str, len);
return res;
}
server:
char buffer[8192];
char *name = readStr(connfd);
if (!name) {
// error handling ...
sendStr(connfd, "Socket read error");
return;
}
printf("name:%s\n", name);
int32_t filesize;
if (readInt32(connfd, &filesize) <= 0) {
// error handling ...
free(name);
sendStr(connfd, "Socket read error");
return;
}
printf("size:%d\n", filesize);
if ((stream = fopen(name, "wb")) == NULL) {
// error handling ...
printf("The file was not opened!\n");
free(name);
sendStr(connfd, "File not opened");
return;
}
while (filesize > 0) {
int numread = readData(connfd, buf, min(filesize, sizeof(buffer)));
if (numread <= 0) {
// error handling ...
close(stream);
free(name);
sendStr(connfd, "Socket read error");
return;
}
printf("buf:%.*s\n", numread, buf);
if (fwrite(buf, 1, numread, stream) != numread) {
// error handling ...
close(stream);
free(name);
sendStr(connfd, "File write error");
return;
}
filesize -= numread;
}
fclose(stream);
free(name);
sendStr(connfd, "OK");
client:
char buffer[8192];
struct stat st;
if (stat( put_name, &st ) != 0) {
// error handling ...
exit(0);
}
if ((stream = fopen(put_name, "rb")) == NULL) {
// error handling ...
printf("The file was not opened!\n");
exit(0);
}
if (sendStr(fd, put_name) <= 0) {
// error handling ...
close(stream);
exit(0);
}
int32_t filesize = st.st_size;
if (sendInt32(fd, filesize) <= 0) {
// error handling ...
close(stream);
exit(0);
}
int lengsize;
while (filesize > 0) {
lengsize = fread(buffer, 1, min(filesize , sizeof(buffer)), stream);
if (lengsize <= 0) {
printf("Read File Failed\n");
// error handling ...
close(stream);
exit(0);
}
if (sendData(fd, buffer, lengsize) <= 0) {
printf("Send File Failed\n");
// error handling ...
close(stream);
exit(0);
}
filesize -= lengsize;
}
close(stream);
char *resp = readStr(fd);
if (!resp) {
// error handling ...
exit(0);
}
if (strcmp(resp, "OK") == 0)
printf("Send File OK\n");
else
printf("Send File Failed: %s\n", resp);
free(resp);

C programm hangs when recv() not expected amount of bytes

I have server side app in C that must read data and process it. Now it handles two messages: send screenshot to client and click mouse. When debugging I found that it receives 16 bytes when client ask a screenshot, but when I send click mouse message, server receives 32 bytes and hangs. Why is that happening and how to process all incoming packets correctly? I'am pretty new at winsock and there not much explaning informations or example how to handle data in wild. Here's the main code of server:
struct coord
{
int x;
int y;
};
struct send_packet
{
int magic;
int cmd;
coord Coords;
};
struct recv_packet
{
int magic;
int code;
int length;
BYTE body[0];
};
do
{
ZeroMemory(&buff, BUFLEN);
int numRcvBytes = 0;
while (numRcvBytes < sizeof(send_packet))
{
iResult = recv(ClientSocket, buff + numRcvBytes, BUFLEN, 0);
//if (iResult <= 0)
// closesocket(ClientSocket);
if (iResult == SOCKET_ERROR)
{
printf("Error %d", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
}
numRcvBytes += iResult;
}
numRcvBytes = 0;
if (iResult > 0)
{
send_packet *pkt;
pkt = (send_packet *)buff;
printf("magc %d cmd %d\n", pkt->magic, pkt->cmd);
printf("Received %d %s\n", iResult, buff);
printf("m:%d c:%d x:%d y:%d\n", pkt->magic, pkt->cmd, pkt->Coords.x, pkt->Coords.y);
int command = pkt->cmd;
recv_packet *rcv_pkt;
int buff_size = 0;
BYTE *data_buffer = NULL;
int size;
int coordX;
int coordY;
wchar_t message[512];
switch (command)
{
case GET_SCREEN:
data_buffer = GetScreeny(75, &buff_size);
rcv_pkt = (recv_packet *)malloc(sizeof(recv_packet)+buff_size);
rcv_pkt->magic = MAGIC;
rcv_pkt->code = 0;
rcv_pkt->length = buff_size;
memcpy(rcv_pkt->body, data_buffer, buff_size);
size = sizeof(rcv_pkt->magic) + sizeof(rcv_pkt->code) + sizeof(rcv_pkt->length) + buff_size;
if (send(ClientSocket, (char *)rcv_pkt, size, 0) == SOCKET_ERROR)
{
printf("Error %d\n", WSAGetLastError());
closesocket(ClientSocket);
//WSACleanup();
//return 1;
}
free(rcv_pkt);
break;
case CLICK_MOUSE:
coordX = pkt->Coords.x;
coordY = pkt->Coords.y;
//wsprintf(message, L"x:%d y:%d", coordX, coordY);
//MessageBox(NULL, message, NULL, MB_OK);
MoveMouse(coordX, coordY);
ClickMouse();
break;
default:
break;
}
/*
char send_buff[1024+1] = "";
ZeroMemory(&send_buff, 1025);
memset(send_buff, 'A', 1024);
recv_packet *rcv_pkt = (recv_packet *)malloc(sizeof(recv_packet)+1024+1);
//recv_packet rcv_pkt = { 0 };
rcv_pkt->magic = MAGIC;
rcv_pkt->code = 0;
rcv_pkt->length = strlen(send_buff)+1;
memcpy(rcv_pkt->body, send_buff, 1025);
int size = sizeof(rcv_pkt->magic) + sizeof(rcv_pkt->code) + sizeof(rcv_pkt->length) + 1024 + 1;
//printf("%d", size);
//getchar();
//return 0;
*/
}
} while (iResult > 0);
I would appreciate any help! Thank you.
You should only read one message at a time. If there are 2 messages available in the socket, your current code will read both but only handle the first.
Change your read to:
iResult = recv(ClientSocket, buff + numRcvBytes, sizeof(send_packet) - numRcvBytes, 0);
Even better would be to extract the receiving to a separate function:
int recvBytes(int socket, size_t numBytes, void *buffer) {
int numRcvBytes = 0;
while (numRcvBytes < numBytes)
{
iResult = recv(socket, buff + numRcvBytes, numBytes - numRcvBytes, 0);
if (iResult == SOCKET_ERROR)
{
// Leave cleanup to caller
return SOCKET_ERROR;
}
numRcvBytes += iResult;
}
return numRcvBytes;
}

send a file without waiting the reception of the whole file

I have a Server that contact another Server in order to obtain a file and then send it to the Client. I have write this piece of code (C - Linux) but only the first 4 bytes arrive to the Client.
Someone better than me can see the mistake?
Thank you very much
int Recv_file (int s, int f, char *ptr, size_t maxlen){
int const TIMEOUT = 60; /* 60 seconds */
size_t n;
ssize_t nread;
ssize_t nsend;
char c;
fd_set cset;
struct timeval tval;
int x;
for (n=1; n<maxlen; n++)
{
FD_ZERO(&cset);
FD_SET(s, &cset);
tval.tv_sec = TIMEOUT;
tval.tv_usec = 0;
x = select(FD_SETSIZE, &cset, NULL, NULL, &tval);
if (x==-1) {
perror("select() failed");
return -1; /* -1 = close connection with the client */
}
if (x>0) {
nread=recv(s, &c, 1, 0);
if (nread == 1)
{
*ptr++ = c;
nsend = Send(f,&c,1);
if (nsend != 1) {
return -1; /* close connection with the client */
}
}else if (nread == 0){
*ptr = 0;
return (-1); /* close connection with the client */
}
else
return (-1); /* close connection with the client */
}else{
printf("(It's been %d seconds and I have not received any response",TIMEOUT);
close(s);
return(-1); /* close connection with the client */
}
}
*ptr = 0;
return (n); /* n == maxlen */
}
with:
int Send(int s, char *ptr, size_t nbytes){
size_t nleft;
ssize_t nwritten;
for (nleft=nbytes; nleft > 0; )
{
nwritten = send(s, ptr, nleft, 0);
if (nwritten <=0)
return (nwritten);
else
{
nleft -= nwritten;
ptr += nwritten;
}
}
return (nbytes - nleft); /* number of bytes sent */
}
UPDATE:
While waiting for an answer I modified:
nread=recv(s, &c, 1, 0); in nread=recv(s, &c, sizeof(c), 0);
and
Send(f,&c,1); in Send(f,&c,sizeof(c));
But now I don't receive the last bytes of the file!
Thank you again!
You don't get the last byte because the for loop start at 1
for (n=1; n<maxlen; n++);
// it should be
for (n=0; n<maxlen; n++);
// or either
for (n=1; n<=maxlen; n++);
EDIT: Also, you could read as much bytes as are available not just one by one, in fact you are sending in the correct way,
For example:
int bLeft = maxlen;
while (bLeft > 0)
{
FD_ZERO(&cset);
FD_SET(s, &cset);
tval.tv_sec = TIMEOUT;
tval.tv_usec = 0;
x = select(FD_SETSIZE, &cset, NULL, NULL, &tval);
if (x > 0) {
nread=recv(s, ptr, bLeft , 0);
if (nread > 0)
{
nsend = Send(f, ptr, nread, 0);
if (nsend <= 0) {
return -1; /* close connection with the client */
}
ptr+ = nread;
bLeft -= nread;
}else if (nread == 0){
*ptr = 0;
return (-1); /* close connection with the client */
}
else
return (-1); /* close connection with the client */
}else{
printf("(It's been %d seconds and I have not received any response",TIMEOUT);
close(s);
return(-1); /* close connection with the client */
}
}
// I would not recommended this, you should adhere to a maxlen length
// assuming there is more space could lead to a memory Exception.
ptr++;
*ptr ='\0';
return (maxlen-bLeft);

Client reads lesser bytes than Server is sending on sockets

My server code is as follows:
while(bytes_written < filesize){
//Send from send_ptr
bw = send(child_socket, send_ptr, newLength, 0);
printf("%d bytes written\n", (int)bw);
//Increment bytes written
bytes_written += bw;
//Move send pointer
send_ptr = send_ptr + bw;
}
And my client code is as follows:
while((num_bytes_recv = read(sd, jpgBufferPointer, BUFFER_LENGTH))>0){
total_bytes_recv += num_bytes_recv;
printf("Read %d bytes\n",num_bytes_recv);
//Check for error
if(jpgError == NULL)
jpgError = strstr(jpgBufferPointer, "404 Not Found");
if(jpgError != NULL){
//Forwarding error response
if(send(sd, jpgBuffer, num_bytes_recv, 0) == -1){
error("Failed to send response message to client");
}
}
else{
//Find content size
contentSizeBuffer = strstr(jpgBufferPointer,"Content-Length");
if(contentSizeBuffer != NULL){
contentSizeBuffer=contentSizeBuffer+16;
contentSize=atoi(contentSizeBuffer);
jpgBuffer=(char*)realloc(jpgBuffer,(contentSize+FILE_NAME_LENGTH*2)*sizeof(char));
jpgBufferPointer=jpgBuffer;
}
jpgBufferPointer+=num_bytes_recv;
}
}
The server is saying it has sent all 43000 bytes, but client says it has received only 32768 bytes.
Appreciate any help! Thanks
You have a bug in the sending part, you should update newLength, because if you have 1 byte left to send from the file, it will send more, going out of the memory area where the content you want to send is stored. You should fix in this way:
bw = send(child_socket, send_ptr, newLength<(filesize-bytes_written)?newLength:(filesize-bytes_written), 0);
In this way the last send will have the correct size.
Also, use write instead of send if you are not using any flags.
You need to have the similar loop as you have on the writing side (bytes_written < filesize) on the reading side (i.e., while you can read more bytes, you should read them and append them).
The network doesn't guarantee that one read() call will return all available data.
The best way of writing client-server socket programming is to have a header before your data. The header should state the amount of data that it is going to transfer.
For example, To send data "Hello World", then send it as "0011+HELLO WORLD"
Here 11 stands for the size of the data the sender is planning to send now. The receiver on reading the first 4 bytes can understand that he should be ready to read next 11 bytes of data from the sender.
So reader will do two read:
hRead = 5 /* With 5 you are saying it can read upto max of 9999 bytes from data".
read(sd, buff, hRead);
dRead = atoi(buff);
readn(sd, buff, dRead);
For Example : Server
size_t sendn(int fd, const void *vptr, size_t n) {
size_t nleft;
size_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nwritten = send(fd, vptr, nleft, 0)) <= 0) {
if (errno == EINTR)
nwritten = 0;
else {
fprintf(stderr, "send failed %d - %s\n", fd, strerror(errno));
return (-1);
}
}
nleft -= nwritten;
ptr += nwritten;
}
return (n);
}
To send message:
sprintf(buff, "%d + %d + %s\r\n", MSG_LOGIN, strlen("Hello World"), Hello World);
sendn(sd, buff, strlen(buff));
Client:
size_t readn(int fd, void *vptr, size_t n) {
size_t nleft;
size_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = recv(fd, ptr, nleft, 0)) < 0) {
if (errno == EINTR)
nread = 0;
else {
fprintf(stderr, "read failed %d - %s\n", fd, strerror(errno));
return (-1);
}
} else if (nread == 0)
break;
nleft -= nread;
ptr += nread;
}
return (n - nleft);
}

Resources