#define million 1000000L
timer_t firstTimerID, secondTimerID, thirdTimerID;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster;
struct sockaddr_in addr, client;
int acceptSocket;
char buf[256];
long rc, sentbytes;
int port = 18033;
void TASK1(Task2ms_Raster)
{
struct timespec start, stop;
uint32 startTime, stopTime;
if( (startTime = clock_gettime( CLOCK_REALTIME, &start)) == -1 ) {
perror("clock gettime");
}
startTime =start.tv_sec + 0.0000001 * start.tv_nsec;
// printf("start time is %lf", StartTime);
// return EXIT_SUCCESS;
/* Trigger DAQ for the 2ms XCP raster. */
if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_2msRstr( ))
{
++numDaqOverload2ms;
}
/* Update those variables which are modified every 2ms. */
counter32 += slope32;
/* Trigger STIM for the 2ms XCP raster. */
if( enableBypass2ms )
{
if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_2msRstr( ) )
{
++numMissingDto2ms;
}
}
if( (stopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) {
perror( "clock gettime" );
}
stopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec;
//printf("stop time is %ld", stopTime);
duration2ms = (uint32)(stopTime- startTime);
// printf( "time difference is= %ld\n", duration2ms );
}
void TASK3(Task100ms_Raster)
{
struct timespec start, stop;
uint32 startTime, stopTime;
if( (startTime = clock_gettime( CLOCK_REALTIME, &start)) == -1 )
{
perror("clock gettime");
}
startTime =start.tv_sec + 0.0000001 * start.tv_nsec;
// printf("start time is %lf", startTime);
/* Trigger DAQ for the 100ms XCP raster. */
if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_100msRstr( ))
{
++numDaqOverload100ms;
}
/* Update those variables which are modified every 100ms. */
counter8 += slope8;
/* Trigger STIM for the 100ms XCP raster. */
if( enableBypass100ms )
{
if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_100msRstr( ) )
{
++numMissingDto100ms;
}
}
if((stopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) {
perror( "clock gettime" );
}
stopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec;
// printf("stop time is %lf", stopTime);
Xcp_CmdProcessor();
duration100ms = ( stop.tv_sec - start.tv_sec )
+ (double)( stop.tv_nsec - start.tv_nsec )
/ (double)million;
// printf( "time difference is= %ld\n", duration100ms );
}
/*The handler checks that the value stored in sival_ptr matches a given timerID
variable. The sival_ptr is the same as the one we set in makeTimer(),
though here it lives in a different structure.
Obviously, it got copied from there to here on the way to this signal handler.
The point is that the timerID is what is used to determine which timer just went off
and determine what to do next */
static void timerHandler( int sig, siginfo_t *si, void *uc )
{
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if ( *tidp == firstTimerID )
TASK1(Task2ms_Raster);
else if ( *tidp == secondTimerID )
TASK2(Task10ms_Raster);
else if ( *tidp == thirdTimerID )
TASK3(Task100ms_Raster);
}
/*
The function takes a pointer to a timer_t variable that will be filled with the
timer ID created by timer_create(). This pointer is also saved in the sival_ptr
variable right before calling timer_create(). In this function notice that we
always use the SIGRTMIN signal, so expiration of any timer causes this signal to
be raised. The signal handler I've written for that signal is timerHandler.
*/
static int makeTimer( char *name, timer_t *timerID, int expireMS, int intervalMS )
{
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;
/* Set up signal handler. */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timerHandler;
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1)
{
perror("sigaction");
}
/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 1000000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 1000000;
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
int CreateSocket()
{
socklen_t len = sizeof(client);
// Socket creation for UDP
acceptSocket=socket(AF_INET,SOCK_DGRAM,0);
if(acceptSocket==-1)
{
printf("Failure: socket creation is failed, failure code\n");
return 1;
}
else
{
printf("Socket started!\n");
}
memset(&addr, 0, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr));
if(rc== -1)
{
printf("Failure: listen, failure code:\n");
return 1;
}
else
{
printf("Socket an port %d \n",port);
}
if(acceptSocket == -1)
{
printf("Fehler: accept, fehler code:\n");
return 1;
}
else
{
while(rc!=-1)
{
rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len);
if(rc==0)
{
printf("Server has no connection..\n");
break;
}
if(rc==-1)
{
printf("something went wrong with data %s", strerror(errno));
break;
}
XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );
// create a timer
makeTimer("First Timer", &firstTimerID, 2, 2); //2ms
makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms
makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms
}
}
close(acceptSocket);
return 0;
}
int main()
{
Xcp_Initialize();
CreateSocket();
return 0;
}
void XcpApp_IpTransmit( uint16 XcpPort, Xcp_StatePtr8 pBytes, uint16 numBytes )
{
if ((long)XcpPort==port){
sentbytes = sendto(acceptSocket,(char*)pBytes,(long)numBytes,0, (struct sockaddr*)&client, sizeof(client));
}
XcpIp_TxCallback(port,(uint16)sentbytes);
}
我正在研究客户端和服务器体系结构。服务器代码如上所示,我创建了一个套接字以通过ip地址和端口号接收来自客户端的请求。服务器正在等待客户端的请求,并将响应发送回客户端。我还创建了计时器,每2ms,10ms和100ms调用一次te任务。我尚未为计时器任务创建单独的线程。刚刚创建了一个要处理的处理程序(信号处理程序)。当客户端向服务器发送请求时,我正在recvfrom api中接收数据,后来它正在调用maketimer(时间为2ms),此后它不会退出2ms任务。
客户端是用于将数据发送到服务器的工具(INCA)。我正在Linux操作系统上工作。
有人可以告诉我上面程序有什么问题吗?
最佳答案
您需要为while(rc!=-1)循环创建单独的线程,因为recvfrom()是阻塞函数。它将线程置于非活动状态,直到出现新数据。
关于c - 如何并行运行功能?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22017825/