1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
| #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <netdb.h> #include <stdarg.h> #include <stdlib.h> #include <signal.h> extern int errno; int errexit(const char *format, ...); int passiveTCP(const char *service, int qlen); int errexit(const char *format, ...); int passivesock(const char *service, const char *transport, int qlen); void handler(int num) { int status; int pid = waitpid(-1, &status, WNOHANG); if (WIFEXITED(status)) { printf("The child %d exit with returing %d\n", pid, WEXITSTATUS(status)); } } unsigned short portbase = 0; #define QLEN 32 #define NAMELEN 32 #define BUFSIZE 8102
int main(int argc, char *argv[]) { struct sockaddr_in fsin; char *service = "echo"; int msock, ssock; unsigned int alen; char file[NAMELEN+1]; char buf[BUFSIZE]; FILE *fp = NULL; char *find; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPecho [port]\n"); } msock = passivesock(service, "tcp", QLEN); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); signal(SIGCHLD,handler); int pid = fork(); if (pid == 0) { if (ssock < 0) errexit("accept failed: %s\n", strerror(errno)); if (read(ssock, file, sizeof file) > 0) { if (file[strlen(file)-1] == '\n') file[strlen(file)-1] = '\0'; fp = fopen(file, "r"); if (NULL == fp) { strcpy(buf, "file open Fail!"); (void) write(ssock, buf, sizeof buf); memset(buf, 0, sizeof buf); return -1; } fread(buf, 1, sizeof buf, fp); fclose(fp); fp = NULL; (void) write(ssock, buf, sizeof buf); memset(buf, 0, sizeof buf); } (void) close(ssock); return 1; } } }
int passivesock(const char *service, const char *transport, int qlen)
{ struct servent *pse; struct protoent *ppe; struct sockaddr_in sin; int s, type; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; if ( pse = getservbyname(service, transport) ) sin.sin_port = htons(ntohs((unsigned short)pse->s_port) + portbase); else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0) errexit("can't get \"%s\" service entry\n", service); if ( (ppe = getprotobyname(transport)) == 0) errexit("can't get \"%s\" protocol entry\n", transport); if (strcmp(transport, "udp") == 0) type = SOCK_DGRAM; else type = SOCK_STREAM; s = socket(PF_INET, type, ppe->p_proto); if (s < 0) errexit("can't create socket: %s\n", strerror(errno)); if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) errexit("can't bind to %s port: %s\n", service, strerror(errno)); if (type == SOCK_STREAM) if (listen(s, qlen) < 0) errexit("can't listen on %s port: %s\n", service, strerror(errno)); return s; } int errexit(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); exit(1); }
|