drBatty пишет:Peter пишет:Приведу попозже, но там именно то, что я описал: помещение gettimeofday() после sendto()
каким-то образом на неё влияет.
вангую, что вы как-то не правильно делаете, и добились UB.
Однако в Astra Linux (Debian Wheezy), эта программа работает. Вот её код с отступами:
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <bool.h>
//#include <cam_udp.h>
typedef union uns_short_int {
unsigned short int us;
unsigned char ch[2];
} uns_short_int;
int main() {
struct timeval tv1, tv2;
unsigned long long int nt1;
uns_short_int usi;
socklen_t lenf;
int i, j, m1, n, ncyc, nfdc, nj, nfds, nfd, nr, len, lencp, lenj;
bool b;
char buf[192];
unsigned char bufr[1024];
unsigned short int uvp = 50616, ucp = 50700; //ucp=COMMAND_PORT;
unsigned int usc = 62;
struct sockaddr_in addrcs, addrcc, addrvs;
FILE *fin, *fout;
llen:len = sizeof(struct sockaddr_in);
if (len == 0)
goto llen;
fin = fopen("imit_cam_cyc.in", "r");
if (fin != NULL) {
n = fscanf(fin, "%hu%[^\n]", &uvp, buf);
n = fscanf(fin, "%u%[^\n]", &usc, buf);
n = fscanf(fin, "%d%[^\n]", &ncyc, buf);
n = fscanf(fin, "%s%[^\n]", buf, buf + 20);
fclose(fin);
} else {
strcpy(buf, "127.0.0.1");
ncyc = 0;
}
usi.us = 0;
b = true;
usc *= 1000;
fout = fopen("imit_cam_cyc.out", "w");
lencp = 32; //lencp=sizeof(CONTROL_PACKET);
fprintf(fout, "input: %d %d %u %hu %d\n", len, lencp, usc, uvp, ncyc);
fflush(fout);
bzero((void *) &addrcs, len);
bzero((void *) &addrcc, len);
bzero((void *) &addrvs, len);
addrcs.sin_addr.s_addr = INADDR_ANY;
addrcs.sin_family = AF_INET;
addrcs.sin_port = htons(ucp);
nfdc = socket(AF_INET, SOCK_DGRAM, 0);
n = bind(nfdc, (struct sockaddr *) &addrcs, len);
if (n < 0) {
strcpy(buf, strerror(errno));
fprintf(fout, "bind: %d %s\n", errno, buf);
}
while (b) {
n = recvfrom(nfdc, bufr, lencp, MSG_WAITALL,
(struct sockaddr *) &addrcc, &lenf);
if (n < 0) {
strcpy(buf, strerror(errno));
fprintf(fout, "recvrom: %d %s\n", errno, buf);
fflush(fout);
return 0;
}
if (n == lencp) {
fprintf(fout, "request: %d %d\n", n, nfdc);
fflush(fout);
n = sendto(nfdc, bufr, lencp, MSG_DONTROUTE,
(struct sockaddr *) &addrcc, len);
fprintf(fout, "answer: %d\n", n);
fflush(fout);
if (n != lencp) {
strcpy(buf, strerror(errno));
fprintf(fout, "sendto: %d %s\n", errno, buf);
fflush(fout);
return 0;
}
b = 0;
}
}
addrvs = addrcc;
addrvs.sin_port = htons(uvp);
nfds = socket(AF_INET, SOCK_DGRAM, 0);
strcpy(buf + 20, "/home/operator1/work/jpg300/jpg_udp_000");
nj = 20 + strlen(buf + 20);
while (1) {
for (j = 0; j < ncyc; j++) {
sprintf(buf + nj - 3, "%03d", j);
nfd = open(buf + 20, O_RDONLY);
if (nfd < 0) {
strcpy(buf, strerror(errno));
fprintf(fout, "open: %d %s\n", errno, buf);
fflush(fout);
return 0;
}
lenj = lseek(nfd, 0, SEEK_END);
n = lseek(nfd, 0, SEEK_SET);
nr = lenj / 1024;
if (nr * 1024 != lenj) {
fprintf(fout, "lenj: %d %d %s\n", j, lenj, buf + 20);
fflush(fout);
}
gettimeofday(&tv1, NULL);
for (i = 0; i < nr; i++) {
n = read(nfd, bufr, 1024);
bufr[2] = usi.ch[1];
bufr[3] = usi.ch[0];
n = sendto(nfds, bufr, 1024, MSG_DONTROUTE,
(struct sockaddr *) &addrvs, len);
if (n < 0) {
strcpy(buf, strerror(errno));
fprintf(fout, "sendto: %d %d %s\n", i, errno, buf);
fflush(fout);
}
usi.us++;
}
close(nfd);
gettimeofday(&tv2, NULL);
nt1 =
(tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec;
m1 = nt1;
n = usleep(usc - m1);
if (n < 0) {
strcpy(buf, strerror(errno));
fprintf(fout, "usleep: %d %d %s\n", i, errno, buf);
fflush(fout);
}
}
}
fclose(fout);
return 0;
}
А вот её код в удобном для меня виде:
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <bool.h>
//#include <cam_udp.h>
typedef union uns_short_int{
unsigned short int us;
unsigned char ch[2];
}uns_short_int;
int main() {
struct timeval tv1,tv2;
unsigned long long int nt1;
uns_short_int usi;
socklen_t lenf;
int i,j,m1,n,ncyc,nfdc,nj,nfds,nfd,nr,len,lencp,lenj;
bool b;
char buf[192];
unsigned char bufr[1024];
unsigned short int uvp=50616,ucp=50700; //ucp=COMMAND_PORT;
unsigned int usc=62;
struct sockaddr_in addrcs,addrcc,addrvs;
FILE *fin,*fout;
llen: len=sizeof(struct sockaddr_in);if(len==0)goto llen;
fin=fopen("imit_cam_cyc.in","r");if(fin!=NULL){n=fscanf(fin,"%hu%[^\n]",&uvp,
buf); n=fscanf(fin,"%u%[^\n]",&usc,buf); n=fscanf(fin,"%d%[^\n]",&ncyc,buf);
n=fscanf(fin,"%s%[^\n]",buf,buf+20); fclose(fin);}
else{strcpy(buf,"127.0.0.1");ncyc=0;}usi.us=0;b=true;usc*=1000;
fout=fopen("imit_cam_cyc.out","w"); lencp=32; //lencp=sizeof(CONTROL_PACKET);
fprintf(fout,"input: %d %d %u %hu %d\n",len,lencp,usc,uvp,ncyc);fflush(fout);
bzero((void*)&addrcs,len);bzero((void*)&addrcc,len);bzero((void*)&addrvs,len);
addrcs.sin_addr.s_addr=INADDR_ANY;addrcs.sin_family=AF_INET;
addrcs.sin_port=htons(ucp);nfdc=socket(AF_INET,SOCK_DGRAM,0);
n=bind(nfdc,(struct sockaddr*)&addrcs,len);
if(n<0){strcpy(buf,strerror(errno));fprintf(fout,"bind: %d %s\n",errno,buf);}
while(b){n=recvfrom(nfdc,bufr,lencp,MSG_WAITALL,(struct sockaddr*)&addrcc,&lenf
);if(n<0){strcpy(buf,strerror(errno));fprintf(fout,"recvrom: %d %s\n",errno,
buf);fflush(fout);return 0;}if(n==lencp){
fprintf(fout,"request: %d %d\n",n,nfdc);fflush(fout);
n=sendto(nfdc,bufr,lencp,MSG_DONTROUTE,(struct sockaddr*)&addrcc,len);
fprintf(fout,"answer: %d\n",n);fflush(fout);
if(n!=lencp){strcpy(buf,strerror(errno));fprintf(fout,"sendto: %d %s\n",
errno,buf);fflush(fout);return 0;}b=0;}}
addrvs=addrcc;addrvs.sin_port=htons(uvp); nfds=socket(AF_INET,SOCK_DGRAM,0);
strcpy(buf+20,"/home/operator1/work/jpg300/jpg_udp_000");nj=20+strlen(buf+20);
while(1){for(j=0;j<ncyc;j++){sprintf(buf+nj-3,"%03d",j);
nfd=open(buf+20,O_RDONLY);
if(nfd<0){strcpy(buf,strerror(errno));fprintf(fout,"open: %d %s\n",errno,buf);
fflush(fout);return 0;}
lenj=lseek(nfd,0,SEEK_END);n=lseek(nfd,0,SEEK_SET);nr=lenj/1024;
if(nr*1024!=lenj){fprintf(fout,"lenj: %d %d %s\n",j,lenj,buf+20);fflush(fout);}
gettimeofday(&tv1,NULL);for(i=0;i<nr;i++){n=read(nfd,bufr,1024);
bufr[2]=usi.ch[1];bufr[3]=usi.ch[0];
n=sendto(nfds,bufr,1024,MSG_DONTROUTE,(struct sockaddr*)&addrvs,len);
if(n<0){strcpy(buf,strerror(errno));fprintf(fout,"sendto: %d %d %s\n",i,
errno,buf);fflush(fout);}usi.us++;}close(nfd);gettimeofday(&tv2,NULL);
nt1=(tv2.tv_sec-tv1.tv_sec)*1000000+tv2.tv_usec-tv1.tv_usec;m1=nt1;
n=usleep(usc-m1);if(n<0){strcpy(buf,strerror(errno));fprintf(fout,
"usleep: %d %d %s\n",i,errno,buf);fflush(fout);}}}fclose(fout);
return 0;
}
Там включается bool.h, это
#ifndef BOOL_H
#define BOOL_H 1
typedef int bool;
#define true 1
#define false 0
#endif
Если gettimeofday() поместить, например, перед 2-м while(), то sendto() возвращает -1 и заканчивается с ошибкой 22.
То же самое в варианте программы без цикла после sendto(), вернее, когда в цикле всё время передаётся один и тот же файл.
jpg_udp_nnn - это файлы, состоящие из udp-пакетов для очередного jpg, но это не важно, важно, что gettimeofday()
влияет на предидущий вызов sendto().
Пётр.
Пётр.