/* * daytime1/daytime.c -- * * A simple TCP over IPv4/IPv6 daytime client. */ #if 1 #include "tiny/csapp.h" #include #else #include #include #include //#include Contains close() in Visual Studio 7 #include #include #if 0 #include #include #include #include #include #else #include #include #endif #endif #ifndef WSAAPI /* getaddrinfo constants */ #define AI_PASSIVE 1 #define AI_CANONNAME 2 #define AI_NUMERICHOST 4 struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo *ai_next; }; #endif static const char *progname = "Test Client 1"; /* * Establish a connection to a remote TCP server. First get the list * of potential network layer addresses and transport layer port * numbers. Iterate through the returned address list until an attempt * to establish a TCP connection is successful (or no other * alternative exists). */ static int tcp_connect(char *host, char *port) { struct addrinfo hints, *ai_list, *ai; int fd = 0; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; #ifdef WSAAPI int n = getaddrinfo(host, port, &hints, &ai_list); if (n) { fprintf(stderr, "%s: getaddrinfo: %s\n", progname, gai_strerror(n)); exit(EXIT_FAILURE); } #else /* Fill in the server's IP address and port */ struct hostent *hp; struct sockaddr_in serveraddr; if ((hp = gethostbyname(host)) == NULL) return -2; /* check h_errno for cause of error */ bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(atoi(port)); bcopy((char *)hp->h_addr, (char *)&serveraddr.sin_addr.s_addr, hp->h_length); hints.ai_addr = (struct sockaddr *)&serveraddr; hints.ai_addrlen = sizeof(serveraddr); hints.ai_family = AF_INET; hints.ai_protocol = 0; hints.ai_next = NULL; ai_list = &hints; #endif for (ai = ai_list; ai; ai = ai->ai_next) { fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) { continue; } if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) { break; } close(fd); } #ifdef WSAAPI freeaddrinfo(ai_list); #endif if (ai == NULL) { fprintf(stderr, "%s: socket or connect: failed for %s port %s\n", progname, host, port); exit(EXIT_FAILURE); } return fd; } /* * Close a TCP connection. This function trivially calls close() on * POSIX systems, but might be more complicated on other systems. */ static int tcp_close(int fd) { return close(fd); } /* * Create a listening TCP endpoint. First get the list of potential * network layter addresses and transport layer port numbers. Iterate * through the returned address list until an attempt to create a * listening TCP endpoint is successful (or no other alternative * exists). */ static int tcp_listen(char *port) { struct addrinfo hints, *ai_list, *ai; int fd = 0, on = 1; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; #ifdef WSAAPI { int n = getaddrinfo(NULL, port, &hints, &ai_list); if (n) { fprintf(stderr, "%s: getaddrinfo failed: %s\n", progname, gai_strerror(n)); return -1; } } #else struct sockaddr_in serveraddr; bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons(atoi(port)); hints.ai_addr = (struct sockaddr *)&serveraddr; hints.ai_addrlen = sizeof(serveraddr); hints.ai_family = AF_INET; hints.ai_protocol = 0; hints.ai_next = NULL; ai_list = &hints; #endif for (ai = ai_list; ai; ai = ai->ai_next) { fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) { continue; } setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) { break; } close(fd); } #ifdef WSAAPI freeaddrinfo(ai_list); #endif if (ai == NULL) { fprintf(stderr, "%s: bind failed for port %s\n", progname, port); return -1; } if (listen(fd, 42) < 0) { fprintf(stderr, "%s: listen failed: %s\n", progname, strerror(errno)); tcp_close(fd); return -1; } return fd; } /* * Accept a new TCP connection and write a message about who was * accepted to the system log. */ static int tcp_accept(int listen) { struct sockaddr_in ss; socklen_t ss_len = sizeof(ss); // char host[NI_MAXHOST]; // char serv[NI_MAXSERV]; int fd; fd = accept(listen, (struct sockaddr *) &ss, &ss_len); if (fd == -1) { syslog(LOG_ERR, "accept failed: %s", strerror(errno)); return -1; } #if 0 int n = getnameinfo((struct sockaddr *) &ss, ss_len, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST); if (n) { // syslog(LOG_ERR, "getnameinfo failed: %s", gai_strerror(n)); } else { syslog(LOG_DEBUG, "connection from %s:%s", host, serv); } #else { struct hostent *hp; char *haddrp; /* determine the domain name and IP address of the client */ hp = Gethostbyaddr((const char *)&ss.sin_addr.s_addr, sizeof(ss.sin_addr.s_addr), AF_INET); haddrp = inet_ntoa(ss.sin_addr); printf("connection from %s (%s)\n", hp->h_name, haddrp); //syslog(LOG_DEBUG, "connection from %s(%s)", host, serv); syslog(LOG_DEBUG, "connection from %s(%s)", hp->h_name, haddrp); } #endif return fd; } int main(int argc, char **argv) { int fdr,fdc,fdl,con; struct sockaddr_storage peer; socklen_t peerlen = sizeof(peer); char *message,msg[128], *p; ssize_t n,l,l2; size_t nn; //Set up a socket to init a robot to the server if (argc ==1) // fdr=tcp_connect("146.50.1.149","3000"); // pc-unreal fdr=tcp_connect("127.0.0.1","3000"); // localhost else fdr=tcp_connect(argv[1],"3000"); message="INIT {ClassName USARBot.P2AT} {Location 3.63,10.8,-0.446} {Name robot1}\r"; // Position Robot 1 in DM-Mapping printf("%s\n",message); nn = write(fdr, message, strlen(message)); //Set up a socket to connect to the server if (argc ==1) // fdc=tcp_connect("146.50.1.149","5874"); // pc-unreal // fdc=Open_clientfd("127.0.0.1",5874); // localhost fdc=tcp_connect("127.0.0.1","5874"); // localhost else fdc=Open_clientfd(argv[1],atoi(argv[2])); /* Get the socket address of the remote end and convert it * into a human readable string (numeric format). */ n = getpeername(fdc, (struct sockaddr *) &peer, &peerlen); if (n) { fprintf(stderr, "%s: getpeername: %s\n", progname, strerror(errno)); return errno; } #ifdef NEEDED { char host[1025]; // NI_MAXHOST from ws2tcpip.h char serv[32]; // char serv[NI_MAXSERV]; n = getnameinfo((struct sockaddr *) &peer, peerlen, host, sizeof(host), serv, sizeof(serv), 0x02 | 0x08); // NI_NUMERICHOST | NI_NUMERICSERV); if (n) { fprintf(stderr, "%s: getnameinfo: %s\n", // progname, gai_strerror(n)); progname, strerror(n)); return n; } } #endif //Register message="register robot1 146.50.1.56;"; printf("%s\n",message); nn = write(fdc, message, strlen(message)); if (nn != strlen(message)) { fprintf(stderr, "Write Failed\n"); return -1; } printf("Message sent\n"); while ((n = read(fdc, msg, sizeof(msg) - 1)) > 0) { msg[n] = '\0'; p = strstr(msg, ";"); if (p) *p = 0; printf("%s\n", msg); if(msg[0]=='O' && msg[1]=='K'){ //Send listen message message="listen robot1 7795;"; printf("%s\n",message); nn = write(fdc, message, strlen(message)); if (nn != strlen(message)) { fprintf(stderr, "Write Failed\n"); return -1; } printf("Message sent\n"); //Listen at a socket #if 0 { int clientlen; struct sockaddr_in clientaddr; fdl = Open_listenfd(7795); printf("listening to port 7795\n"); } #else fdl = tcp_listen("7795"); #endif //Wait for OK while ((l = read(fdc, msg, sizeof(msg) - 1)) > 0) { msg[l] = '\0'; p = strstr(msg, ";"); if (p) *p = 0; printf("%s\n", msg); if(msg[0]=='O' && msg[1]=='K'){ //Close connection to the server tcp_close(fdc); //Accept the connection #if 0 { int clientlen; struct sockaddr_in clientaddr; clientlen = sizeof(clientaddr); con = Accept(fdl, (SA *)&clientaddr, &clientlen); } #else con=tcp_accept(fdl); // program hangs here #endif printf("accepting client at port 7795\n"); l2 = read(con, msg, sizeof(msg) - 1); #if 0 if (l2 > 0) { printf("Direct message\n"); } else { while(l2 == 0) { printf("%d: Try another message\n",l2); l2 = read(con, msg, sizeof(msg) - 1); }; } #endif //Wait for messages #if 1 while (l2 > 0) { msg[l2] = '\0'; p = strstr(msg, ";"); if (p) *p = 0; //Print the messages printf("%s\n", msg); l2 = read(con, msg, sizeof(msg) - 1); } //Close and exit tcp_close(fdl); #endif break; } } } } return EXIT_SUCCESS; }