📄 peterclient.c
字号:
/* peterclient.c * CMUnited-97 (soccer client for Robocup-97) * Peter Stone <pstone@cs.cmu.edu> * Computer Science Department * Carnegie Mellon University * Copyright (C) 1997 Peter Stone * * CMUnited-97 was created by Peter Stone and Manuela Veloso * * You may copy and distribute this program freely as long as you retain this notice. * If you make any changes or have any comments we would appreciate a message. *//* * udp client program. */#include "global.h"#if PRACTICE#define SAVE_LOG 0#define SAVE_SOUND_LOG 0#else#define SAVE_LOG 0#define SAVE_SOUND_LOG 0#endif#define RECV_DEBUG 0#define TAKE_KBD_INPUT 0#define PRINT_MISSED_MSGS 0int SIMULATOR_STEP = DEFAULT_SIMULATOR_STEP;Socket init_connection(char* host, int port);int send_message(char* buf, Socket *sock);int receive_message(char *buf, int size, Socket *sock, int *port, int flags);int ProcessInitializeMessage(Socket *sock, char *team_name, int unum);void ProcessIncomingMessage(Socket *sock);int ProcessKeyboardInput(Socket *sock, int *behavior, FILE *fpin);void message_loop(FILE* fpin, char* team_name, int unum, Socket *sock, int behavior, int my_score, int their_score);void close_connection(Socket sock);/* Make these Global instead of passing them around */Socket GLOBAL_SOCK;Socket *GLOBAL_sock = &GLOBAL_SOCK;Memory GLOBAL_MEM;Memory *Mem = &GLOBAL_MEM;#if SAVE_LOGFILE *fpout; char fpoutName[MAXMESG];#endif#if SAVE_SOUND_LOGFILE *fpSoundout; char fpSoundoutName[MAXMESG];#endif/* * UDP connection の倡肋 * * 苞眶 : * host : host name もしくは host の IP address * port : port 戎规 * * 提り猛 : * error が券栏した眷圭、Socket.socketfd に -1 を掐れて手す。 * */ Socket init_connection(char *host, int port){ struct hostent *host_ent ; struct in_addr *addr_ptr ; struct sockaddr_in cli_addr ; int sockfd, val ; Socket sock ; sock.socketfd = -1 ; if((host_ent = (struct hostent *)gethostbyname(host)) == NULL) { /* Check if a numeric address */ if(inet_addr(host) == -1){ return sock ; } } else{ addr_ptr = (struct in_addr *) *host_ent->h_addr_list ; host = inet_ntoa(*addr_ptr) ; } /* * Open UDP socket. */ if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ return sock ; /* Can't open socket. */ } val = fcntl(sockfd, F_GETFL, 0) ; /* 5/17/96 Dave found that O_NONBLOCK didn't work for setting up a*/ /* non-blocking socket. O_NDELAY seems to work, though! */ /* val |= O_NONBLOCK ;*/ val |= O_NDELAY; fcntl(sockfd, F_SETFL, val) ; /* * Bind any local address. */ bzero((char *) &cli_addr, sizeof(cli_addr)) ; cli_addr.sin_family = AF_INET ; cli_addr.sin_addr.s_addr = htonl(INADDR_ANY) ; cli_addr.sin_port = htons(0) ; if(bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0){ return sock ; /* Can't bind local address */ } /* * Fill in the structure with the address of the server. */ sock.socketfd = sockfd ; bzero((char *) &sock.serv_addr, sizeof(sock.serv_addr)) ; sock.serv_addr.sin_family = AF_INET ; sock.serv_addr.sin_addr.s_addr = inet_addr(host) ; sock.serv_addr.sin_port = htons(port) ; return sock ;}/* * socket に message を流叫 * * 苞眶 : * buf : message の柒推 * sock : socket * * 提り猛 : * 流叫に己窃した眷圭、-1 を手す。 * */#define TIMER_INIT_SECS 999999 /* Enough so it won't expire */#define TIMER_INIT_USECS 1000*SIMULATOR_STEP#define CHECK_SOCKET_INTERVAL_USECS 10000/* Returns FALSE if there's no time to wait--ready to act right away *//* Returns TRUE if the time ran out: any new messages were parsed */int message_poll_while_waiting(Socket *sock){ struct itimerval itv2; int dummy_port; char buf[MAXMESG]; /* For peaking, this must be big */ struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = CHECK_SOCKET_INTERVAL_USECS; getitimer(ITIMER_REAL, &itv2); if ( itv2.it_value.tv_sec != TIMER_INIT_SECS ) return FALSE; while (itv2.it_value.tv_sec == TIMER_INIT_SECS){ /* changes after TIMER_INIT_USECS */ /* Check for new messages while waiting to act */ /* Right now this is all busy wait. Put in some short usleeps? */ if( receive_message(buf, MAXMESG, sock, &dummy_port, MSG_PEEK) > 0 ){#if RECV_DEBUG /* getitimer(ITIMER_REAL, &itv2); fprintf(fpout,"Player %d, time %d: About to process, timer secs-usecs = %d-%d\n", Mem->MyNumber,Mem->CurrentTime,itv2.it_value.tv_sec,itv2.it_value.tv_usec); */#endif ProcessIncomingMessage(sock);#if RECV_DEBUG /* getitimer(ITIMER_REAL, &itv2); fprintf(fpout,"Player %d, time %d: Processed , timer secs-usecs = %d-%d\n", Mem->MyNumber,Mem->CurrentTime,itv2.it_value.tv_sec,itv2.it_value.tv_usec); */#endif } select(1,0,0,0,&timeout); /* Pause for a bit so as not to busy wait */ getitimer(ITIMER_REAL, &itv2); } return TRUE;}int message_poll_until_sight(Socket *sock){ fd_set readfds; int in, max_fd; Mem->NewSight = FALSE; while ( !Mem->NewSight ){ FD_ZERO(&readfds) ;#if 0 FD_SET(in, &readfds) ;#else in = 0;#endif FD_SET(sock->socketfd, &readfds) ; max_fd = ((in > sock->socketfd) ? in : sock->socketfd) + 1 ; /* Select waits for something on the socket before acting */ if(select(max_fd, &readfds, 0, 0, 0) == -1){ perror("select") ; break ; } if( FD_ISSET(sock->socketfd, &readfds) ){ ProcessIncomingMessage(sock); }#if 0 if( FD_ISSET(in, &readfds) ){ ProcessKeyboardInput(sock,&behavior,fpin); }#endif } Mem->NewSight = FALSE;}int send_message(char *buf, Socket *sock){ int n; static int initialized = FALSE; static struct itimerval itv;#if 0 int StartTime = Mem->CurrentTime;#endif if ( initialized ){ /* Don't act unless it's been enough time */ message_poll_while_waiting(sock); } n = strlen(buf) ; if( sendto(sock->socketfd, buf, n, 0, (struct sockaddr *)&sock->serv_addr, sizeof(sock->serv_addr)) != n ){ my_error("Why getting here? client.c: send_message"); return (-1) ; } if ( initialized ){ setitimer(ITIMER_REAL, &itv, NULL); } else { /* This is the initialize message */ itv.it_interval.tv_sec = 0 ; /* Don't have an fpout yet */ itv.it_interval.tv_usec = 0 ; itv.it_value.tv_sec = TIMER_INIT_SECS; /* So the clock doesn't run down */ itv.it_value.tv_usec = TIMER_INIT_USECS; initialized = TRUE; #if PRACTICE itv.it_value.tv_usec *= DELAY_FACTOR;#endif return 0; } #if SAVE_LOG /*if (Mem->CurrentTime != StartTime) fprintf(fpout, " &&& Following command issued-sent at %d-%d &&&\n", StartTime,Mem->CurrentTime);*/ fprintf(fpout,">>"); fputs(buf, fpout) ;#endif /*usleep(1000 * SIMULATOR_STEP); /* Wait simulator_step to let command execute */ return 0;} /* * socket からの message の减慨 * * 苞眶 : * buf : message を艰り哈む buffer * size : sizeof(buf) * sock : socket * * 提り猛 : * 减慨に己窃した眷圭、-1 を手す。 * 减慨柒推が痰い眷圭、 0 を手す。 * 减慨柒推がある眷圭、 1 を手す。 * */int receive_message(char *buf, int size, Socket *sock, int *port, int flags){ /* flags is usually 0. If it's MSG_PEEK, just check if the message is there */ int n,servlen ; struct sockaddr_in serv_addr ; servlen = sizeof(serv_addr) ;#if RECV_DEBUG struct itimerval itv2; getitimer(ITIMER_REAL, &itv2); int start_secs = itv2.it_value.tv_sec; int start_usecs = itv2.it_value.tv_usec;#endif n = recvfrom(sock->socketfd, buf, size, flags, (struct sockaddr *)&serv_addr, &servlen);#if RECV_DEBUG getitimer(ITIMER_REAL, &itv2); int end_secs = itv2.it_value.tv_sec; int end_usecs = itv2.it_value.tv_usec; if (Mem->CurrentTime > 0) fprintf(fpout," #### Receiving took from %d-%d to %d-%d (%d)####\n", start_secs,start_usecs,end_secs,end_usecs,flags);#endif /* Remember the port for this client */ if (*port == DEFAULT_PORT_NUMBER) /* If this doesn't work, use ntohs(serv_addr.sin_port) */ *port = serv_addr.sin_port; if(n < 0) if( n == -1 && errno == EWOULDBLOCK){ buf[0] = '\0' ; return 0 ; } else return (-1) ; else{ buf[n] = '\0' ; if(n == 0) return 0 ; else return 1 ; }}/* * messege の流减慨 * * 苞眶 : * fpin : 掐蜗(柒推は socket に流り哈まれる) * fpout: 叫蜗(socket からの减慨柒推が流り哈まれる) * sock : socket * */int ProcessInitializeMessage(Socket *sock, char *team_name, int unum){ int port = DEFAULT_PORT_NUMBER, n; int number = unum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -