create socket by pthread
2012-05-30 15:42
225 查看
#include <pthread.h> #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); void *thread_main(void *arg); //-------------------------------------------------------------------- // 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)); //-------------------------------------------------------------- // create new thread //-------------------------------------------------------------- pthread_t tid; pthread_attr_t attr; int code; //int pthread_attr_init(pthread_attr_t *attr); pthread_attr_init(&attr); //int pthread_attr_setdetachstate(pthread_attr_t * attr, int detach - state); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //int pthread_create(pthread_t * restrict thread, const pthread_attr_t * restrict attr, void *(*start_routine) (void *), void *restrict arg); if ((code = pthread_create(&tid, &attr, thread_main, (void *) &new_connected_socket)) != 0) { fprintf(stderr, "[%d]Create new thread failed: %s\n", getpid(), strerror(code)); } else { fprintf(stdout, "[%d]New thread created.\n", getpid()); } //int pthread_attr_destroy(pthread_attr_t *attr); pthread_attr_destroy(&attr); } } //------------------------------------------------------------------ // 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 } } void *thread_main(void *arg) { int fd = *(int *) arg; //-------------------------------------------------------------- // 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(fd, 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(fd); pthread_exit((void *) 0); } // vim:tabstop=8
相关文章推荐
- create socket by fork
- pthread_create源码解析
- 创建线程时,undefined reference to 'pthread_create'问题解决
- How to create physical standby database with 11g RMAN DUPLICATE FROM ACTIVE DATABASE [ID 747250.1]
- 多线程函数系列pthread_create(), pthread_join(), pthread_self(),pthread_exit(), pthread_detach()实例详解
- linux下Qt调用非标准库中的函数调用----------如pthread_create、pthread_cond_***、、
- 使用Mob短信验证出现 java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)异常
- undefined reference to 'pthread_create'问题解决
- undefined reference to `pthread_create'
- pthread_create 参数传递指针问题
- pthread_key_create用法
- pthread_create
- Java Socket Connection reset by peer的原因
- pthread_create函数编译时报错:undefined reference to 'pthread_create'
- 【Cocos2dx通信(Http&Socket)相关编译到Android细节总结】编译加入curl关联lib与头文件 && 解决pthread的cancel函数NDK不支持,找不到sockaddr_i
- study note: undefine reference pthread_create() -2011.4.22
- pthread_create
- Create AD Users by Powershell
- Posix线程中undefined reference to 'pthread_create'问题解决
- pthread_create()给创建的线程传递参数