Socket write file data transfer is not complete (Fu Yuanma)

Everybody is good:
Write a socket program, generally realize function is a server from a port output file forwarded, functions basically completed, but there is the problem of my program transmitting data to another server data loss would occur. But I am in close (socket) sleep (1) is good, still have some doubts. Want to know things are as follows:

1 the program does have read data over write success (the return value of write will not deceive us), the feeling is me close too fast to write the contents of the buffer did not transfer to another server, if so then I in close (socket) before you have what function can confirm the current write buffer what content? Whether it has been transmitted? Try SO_LINGER, not like.

2 if it is not like the first problem is described, what is the problem?

3 the following program in a computer to do the test, the equivalent of a computer to open 2 NC sever port not just, open a program I.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdarg.h>
#include <netdb.h>

#define SERVPORT 8090
#define MAXDATASIZE 1024

int do_con_n(char *address, int port)
{
int s;
struct sockaddr_in sin;
fd_set set;
struct timeval timeo = {15, 0}; //time ou struct
socklen_t len = sizeof(timeo);
int retval;
int error;

s=socket(AF_INET, SOCK_STREAM, 0);
// x=fcntl(s,F_GETFL,0); // Get socket flags
fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); //Set to a non blocking mode
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family=AF_INET;
sin.sin_port=htons(port);
//sin.sin_addr.s_addr=name_resolve(address);
sin.sin_addr.s_addr = inet_addr(address);
if(!sin.sin_addr.s_addr) return(-1);
//printf("ip: %s\n",inet_ntoa(sin.sin_addr));
if(connect(s, (struct sockaddr *)&sin, sizeof(sin))!=0)
{
if (errno != EINPROGRESS)
{
printf("connect:normal network unreach!!");
return -1;
}
FD_ZERO(&set);/*Set cleared the set does not contain any FD*/
FD_SET(s,&set); /*Will a given file descriptor is added to the collection.*/
retval = select(s + 1, NULL, &set, NULL, &timeo);
if (retval == -1)
{
printf("select");
return -1;
}
else if(retval == 0)
{
printf("timeout\n"); //This select is a longer time timeout is blocking mode, more than timeout returns
printf("%d\n", time(NULL));
return 0;
}
else
{
printf("connected--->:[%d]\n",retval);
getsockopt(s, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); //In the judgment of the connected after the success, get some information the current set of interfaces to determine whether it is connected, return 0 really even.
//printf("error--->:[%d]\n",error);

if(0!=error)
{
printf("error--->:[%d]\n",error);
perror("error");
return -1;
}
}

}

return(s);
}

int SeanSend(int fd, void *buffer, int length)
{
int bytes_left;
int written_bytes;
char *ptr=NULL;
ptr=(char *)buffer;
bytes_left=length;

while( bytes_left>0)
{
/* Start writing*/
written_bytes=write(fd, ptr, bytes_left);
//printf("\nin seasend:written_bytes=[%d]\n",written_bytes);
if(written_bytes<=0) /* Wrong*/
{
if(errno==EINTR) /* Interrupt error continues to write?*/
{
printf("[%s]:error errno==EINTR continue\n",__FUNCTION__);
continue;

}
else if(errno==EAGAIN) /* EAGAIN : Resource temporarily unavailable*/
{
//printf("[SeanSend]error errno==EAGAIN continue\n");
usleep(1000);//For preventing CPU%100, hoping to send buffer can be released
continue;

}
else /* Other errors */
{
printf("[%s]:ERROR: errno = %d, strerror = %s \n",__FUNCTION__
, errno, strerror(errno));
return(-1);
}
}
bytes_left-=written_bytes;
ptr+=written_bytes;/* Continue to write from the rest*/
}
return length;
}

int main(int argc, char **argv)
{
int sockfd, recvbytes;
int sockfd1;
int ret;
char rcv_buf[MAXDATASIZE];
char snd_buf[MAXDATASIZE];
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
struct sockaddr_in serv_addr1;
fd_set rdfds;
fd_set rdfds1;
int srvport,srvport1;
struct timeval timeo1 = {3, 0}; //time1 ou struct
int rcvlen=0;
int wrtlen=0;
int rcvlen1=0;
int wrtlen1=0;

if(argc != 4)
{
fprintf(stderr, "Error!.\n");
exit(1);
}

sockfd=do_con_n(argv[1],atoi(argv[2]));
sockfd1=do_con_n(argv[1],atoi(argv[3]));

while(1)
{
FD_ZERO(&rdfds);
FD_SET(sockfd, &rdfds);
FD_SET(sockfd1, &rdfds);

ret = select( (sockfd>sockfd1?sockfd:sockfd1)+1, &rdfds, NULL, NULL, NULL );
if(ret<0)
{
if(errno == EINTR)
continue;
perror("select:");
exit(1);
}
//Note, the current processing use without overtime select, CPU occupancy rate is low, less than%1
else if(ret==0)
{
//printf("\nret==0,timeout\n");
//The select in the first overtime will change the value of timeo1 is 0, so the judges to do a usleep, or in the timeout state when the CPU occupancy as high as 12%
usleep(1000); //This CPU is timeout when the occupancy rate will be lower
continue;
}
else
{
if(FD_ISSET(sockfd, &rdfds))
{
//printf("go\n");
memset(rcv_buf, 0x00, sizeof(rcv_buf));
if((rcvlen=read(sockfd, rcv_buf, MAXDATASIZE))>0)
{
wrtlen=SeanSend(sockfd1,rcv_buf,rcvlen);
//printf("\nwrtlen=[%d]\n",wrtlen);
}
else if(0==rcvlen)
{
break;
}
else
{
printf("sockfed ERROR: errno = %d, strerror = %s \n"
, errno, strerror(errno));
}

}

if(FD_ISSET(sockfd1, &rdfds))
{
//printf("go11\n");
memset(rcv_buf, 0x00, sizeof(rcv_buf));
if((rcvlen1=read(sockfd1, rcv_buf, MAXDATASIZE))>0)
{
wrtlen1=SeanSend(sockfd,rcv_buf,rcvlen1);
//printf("\nwrtlen1=[%d]\n",wrtlen1);
}
else if(0==rcvlen1)
{
break;
}
else
{
printf("sockfed1 ERROR: errno = %d, strerror = %s \n"
, errno, strerror(errno));
}

}
//continue;
}
}
sleep(1);//If no sleep file basically transmission is not full, occasionally received completely
close(sockfd);//TCP one-way closed
close(sockfd1);
return 0;
}

Started by Kennedy at January 06, 2017 - 8:21 PM

The data is not lost, the receiver executes a read function will stop, once the sender write. The receiving end continued operation, at this time because the receiving end just to accept data, and sending end to send data, wrote before the data in rec_buf is covered. I am a novice, please teach me.

Posted by Regan at January 15, 2017 - 8:26 PM