create socket by fork
2012-05-30 15:45
15 查看
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/wait.h> #include <signal.h> #include <time.h> #include <string.h> #include <errno.h> //-------------------------------------------------------------------- // Function prototype //-------------------------------------------------------------------- void signal_handler(int signum); //-------------------------------------------------------------------- // Main function //-------------------------------------------------------------------- int main(int argc, char **argv) { int listening_socket; unsigned short port; int backlog; //------------------------------------------------------------------ // Parse command line arguments //------------------------------------------------------------------ port = (unsigned short) strtol(argv[2], NULL, 10); backlog = (int) strtol(argv[3], NULL, 10); //------------------------------------------------------------------ // step 1, create socket //------------------------------------------------------------------ //int socket(int domain, int type, int protocol); if ((listening_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) { // failed fprintf(stderr, "[%d]Create new TCP socket failed: %s\n", getpid(), strerror(errno)); exit(1); } fprintf(stderr, "[%d]New TCP socket created, listening_socket = %d\n", getpid(), listening_socket); //------------------------------------------------------------------ // Set SO_REUSEADDR & SO_REUSEPORT options //------------------------------------------------------------------ int optval; optval = 1; //int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); if (setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { fprintf(stderr, "[%d]Set socket option SO_REUSEADDR failed: %s\n", getpid(), strerror(errno)); } else { fprintf(stderr, "[%d]Set socket option SO_REUSEADDR successfully.\n", getpid()); } #ifdef SO_REUSEPORT optval = 1; //int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); if (setsockopt(listening_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) < 0) { fprintf(stderr, "[%d]Set socket option SO_REUSEPORT failed: %s\n", getpid(), strerror(errno)); } else { fprintf(stderr, "[%d]Set socket option SO_REUSEPORT successfully.\n", getpid()); } #endif //------------------------------------------------------------------ // step 2, bind //------------------------------------------------------------------ struct sockaddr_in local_ipv4_address; // IPv4 memset(&local_ipv4_address, 0, sizeof(local_ipv4_address)); local_ipv4_address.sin_family = AF_INET; // IPv4 local_ipv4_address.sin_port = htons(port); // Network byte order // int inet_pton(int af, const char *src, void *dst); inet_pton(AF_INET, argv[1], &local_ipv4_address.sin_addr); // Bind all interfaces //local_ipv4_address.sin_addr.s_addr = INADDR_ANY; //int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); if (bind(listening_socket, (struct sockaddr *) &local_ipv4_address, sizeof(local_ipv4_address)) < 0) { fprintf(stderr, "[%d]Bind to %s:%d failed: %s\n", getpid(), argv[1], port, strerror(errno)); close(listening_socket); exit(1); } fprintf(stderr, "[%d]Bound to %s:%d successfully.\n", getpid(), argv[1], port); //------------------------------------------------------------------ // step 3, listen //------------------------------------------------------------------ //int listen(int sockfd, int backlog); if (listen(listening_socket, backlog) < 0) { fprintf(stderr, "[%d]Listen on %s:%d failed: %s\n", getpid(), argv[1], port, strerror(errno)); close(listening_socket); exit(1); } fprintf(stderr, "[%d]Listen on %s:%d successfully.\n", getpid(), argv[1], port); fprintf(stderr, "[%d]Waiting for incomming connections ...\n", getpid()); //------------------------------------------------------------------ // Register signal handler //------------------------------------------------------------------ struct sigaction act, oact; #if 0 struct sigaction { void (*sa_handler) (int); void (*sa_sigaction) (int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer) (void); }; #endif memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; //int sigemptyset(sigset_t *set); sigemptyset(&act.sa_mask); act.sa_flags = 0; //int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); sigaction(SIGCHLD, &act, &oact); //------------------------------------------------------------------ // Main loop //------------------------------------------------------------------ for (;;) { //---------------------------------------------------------------- // accept(), create a new_connected_socket //---------------------------------------------------------------- /* * The accept() system call is used with connection-based socket types (SOCK_STREAM, SOCK_SEQPACKET). * * It extracts the first connection request on the queue of pending connections, creates a new connected * socket, and returns a new file descriptor referring to that socket. * * The newly created socket is not in the listening state(in ESTABLISHED state) * * The original socket sockfd is unaffected by this call(still in LISTEN state) */ int new_connected_socket; struct sockaddr_in peer_ipv4_address; socklen_t peer_ipv4_address_length; // peer_ipv4_address_length is a value-result parameter peer_ipv4_address_length = sizeof(peer_ipv4_address); //int accept(int sockfd, struct sockaddr *addr, socklen_t * addrlen); if ((new_connected_socket = accept(listening_socket, (struct sockaddr *) &peer_ipv4_address, &peer_ipv4_address_length)) < 0) { // failed if (errno == EINTR) { // Interrupted by signal continue; } else { // TODO: check other error code } fprintf(stderr, "[%d]Accept new connections on socket %d failed: %s\n", getpid(), listening_socket, strerror(errno)); break; } else { // success char peer_ipv4_address_string[] = "ddd.ddd.ddd.ddd"; //const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); inet_ntop(AF_INET, &peer_ipv4_address.sin_addr, peer_ipv4_address_string, sizeof(peer_ipv4_address_string)); fprintf(stderr, "[%d]Accepted a new connection %d from %s:%d.\n", getpid(), new_connected_socket, peer_ipv4_address_string, ntohs(peer_ipv4_address.sin_port)); pid_t pid; if ((pid = fork()) < 0) { // failed fprintf(stderr, "[%d]Create new process failed: %s\n", getpid(), strerror(errno)); //FIXME: How to do? } else if (pid == 0) { // child process close(listening_socket); //-------------------------------------------------------------- // Compose current time information //-------------------------------------------------------------- // time_t time(time_t *t); time_t now = time(NULL); struct tm *tm; //struct tm *localtime(const time_t *timep); tm = localtime(&now); char buffer[128]; #if 0 struct tm { int tm_sec; /* seconds */ int tm_min; /* minutes */ int tm_hour; /* hours */ int tm_mday; /* day of the month */ int tm_mon; /* month */ int tm_year; /* year */ int tm_wday; /* day of the week */ int tm_yday; /* day in the year */ int tm_isdst; /* daylight saving time */ }; #endif memset(buffer, 0, sizeof(buffer)); //int snprintf(char *str, size_t size, const char *format,...); snprintf(buffer, sizeof(buffer) - 1, "Current time: %04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); //-------------------------------------------------------------- // Send current time to client //-------------------------------------------------------------- ssize_t n; //ssize_t write(int listening_socket, const void *buf, size_t count); if ((n = write(new_connected_socket, buffer, strlen(buffer))) < 0) { fprintf(stderr, "[%d]Send data to client fialed: %s\n", getpid(), strerror(errno)); } else { fprintf(stderr, "[%d]Sent %d bytes (\"%s\" to client successfully.\n", getpid(), n, buffer); } //-------------------------------------------------------------- // close new_connected_socket //-------------------------------------------------------------- close(new_connected_socket); exit(0); // child process termination, very important } else { // parent close(new_connected_socket); } } } //------------------------------------------------------------------ // final, close listening_socket //------------------------------------------------------------------ close(listening_socket); return 0; } void signal_handler(int signum) { fprintf(stderr, "[%d]Caught signal %d.\n", getpid(), signum); pid_t pid; int status; //pid_t wait(int *status); if ((pid = wait(&status)) < 0) { // failed fprintf(stderr, "wait() failed: %s\n", strerror(errno)); } else { fprintf(stderr, "[%d]Child process %d terminated, status = 0x%08x\n", getpid(), pid, status); // check status } } // vim:tabstop=8
相关文章推荐
- create socket by pthread
- How to create physical standby database with 11g RMAN DUPLICATE FROM ACTIVE DATABASE [ID 747250.1]
- Android与PC的Socket(TCP/IP)通信(by USB) 拒绝连接的
- java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
- Simply Implementing Communication By Muti-Thread From Socket
- ab压测 apr_socket_recv: Connection reset by peer (104)错误解决方法
- create dll formt lib with cpp funcs or c just funcs by hand.
- ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error"异常原因分析
- dynamic create option element for select by javascript
- Sliverlight : dynamic Create page by parameter
- request time failed: java.net.SocketException: Address family not supported by protocol
- nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
- java.net.SocketException:connection reset by peer:socket write error
- Step by Step - How to create a c++ library with NDK on Android Studio 1.5 (not experimental way)
- php socket_create undefined的错误解决办法
- 解决nodejs socket.io is not allowed by Access-Control-Allow-Origin 跨域问题
- java.net.SocketException: Unrecognized Windows Sockets error: 10106: create" which imposes a more or
- Step-By-Step Guide To Create Physical Standby On Normal File System For ASM Primary using RMAN (文档 I
- BW--Create Data Warehousing: Step by Step(摘自SAP Library)
- Unable to create directory wp-content/uploads/2016/12. Is its parent directory writable by the serve