接上篇博文,本文是server端的实现,主要实现的功能,就是现实client的连接。转发client发送的消息。以及client掉线提示等功能,同一时候能够在这这上面扩展和TCP以及线程相关的功能木块。
tcpreceive.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#ifndef TCPRECEIVE_H #define TCPRECEIVE_H #define BUFFSIZE 2048 #define listen_max 5 int cond; int rscond; typedef struct TCP_rcv_arg { char *local_addr; int tcp_port; }TCP_rcv_arg_t; void stop_handler(int signum); void *tcppackrecv(void *arg); #endif |
tcpreceive.c
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 |
#include "tcpreceive.h" #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/param.h> #include <arpa/inet.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include <ctype.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <pthread.h> void stop_handler(int sinnum) { cond = 0; rscond = 0; } void *tcppackrecv(void *arg) { int listen_fd,client_id,len = 1; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size; fd_set master; fd_set read_fds; int fdmax,i,newfd,j; char buf[BUFFSIZE + 1]; TCP_rcv_arg_t *rcv_arg = (TCP_rcv_arg_t *)arg; sin_size = sizeof(client_addr); if(-1 == (listen_fd = socket(AF_INET,SOCK_STREAM,0))) { fprintf(stderr,"Socket Error:%s\n",strerror(errno)); pthread_exit(NULL); } memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //server_addr.sin_addr.s_addr = inet_addr((*rcv_arg).local_addr); server_addr.sin_port = htons((*rcv_arg).tcp_port); setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&len,sizeof(len)); if( -1 == bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr))) { fprintf(stderr,"Bind Error:%s\n",strerror(errno)); pthread_exit(NULL); } if(-1 == listen(listen_fd,listen_max)) { fprintf(stderr,"Listen Error:%s\n",strerror(errno)); pthread_exit(NULL); } //printf("listen ok!\n"); FD_ZERO(&master); FD_ZERO(&read_fds); FD_SET(listen_fd,&master); fdmax = listen_fd; cond = 1; while(cond) { read_fds = master; if(-1 == select(fdmax+1,&read_fds,NULL,NULL,NULL)) { fprintf(stderr,"Server Select Error:%s\n",strerror(errno)); pthread_exit(NULL); } for(i = 0;i <= fdmax;i++) { if(FD_ISSET(i,&read_fds)) { if(i == listen_fd) { if(-1 == (newfd = accept(listen_fd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size))) { fprintf(stderr,"Accept Error:%s\n",strerror(errno)); } else { FD_SET(newfd,&master); if(newfd > fdmax) { fdmax = newfd; } sprintf(buf,"Your SocketID is:%d.",newfd); if(send(newfd,buf,21,0) < 0) { printf("Send Error!\n"); } printf("there is a new connection in,form %s,SocketID is %d.\n",inet_ntoa(client_addr.sin_addr),newfd); } } else { sprintf(buf,"Form %2d:\n",i); if((len = recv(i,buf + 9,BUFFSIZE - 10,0)) <= 0) { if(0 == len) { printf("SocketID %d has left!\n",i); } else { perror("the recv() go end!\n"); } close(i); FD_CLR(i,&master); } else { len += 9; buf[len] = ‘\0‘; printf("%s\n",buf); for(j = 0;j <= fdmax;j++) { if(FD_ISSET(j,&master) && j != listen_fd && j !=i) { if(-1 == send(j,buf,len,0)) { perror("Send() error!\n"); } } } } } } } } pthread_exit(NULL); } |
server.c
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 |
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <pthread.h> #include <errno.h> #include "tcpreceive.h" #define PORT 8888 #define IP "192.168.1.220" int main() { pthread_t tid; pthread_t id; void *tret; TCP_rcv_arg_t rcv_arg; rcv_arg.tcp_port = PORT; rcv_arg.local_addr = IP; printf("the main process!\n"); int i= pthread_create(&tid,NULL,(void *)tcppackrecv,(void *)&rcv_arg); if( i != 0) { printf("Create pthread error!\n"); pthread_exit(NULL); } if (0 != pthread_join(tid, &tret)) { printf("Join pthread error!\n"); } return 0; } |
为了大家编译方便,将Makefile也放上来:
1 2 3 4 5 6 7 8 9 10 |
all: gcc -c tcpsed.c ar cr libtcpsed.a tcpsed.o gcc -c tcpreceive.c ar cr libtcpreceive.a tcpreceive.o gcc -o server server.c -L. -ltcpreceive -lpthread gcc -o client client.c -L. -ltcpsed -lpthread clean: rm -rf *.o *.a server client |
CSDN上面源代码下载地址:
http://download.csdn.net/detail/u012377333/8079943
1 2 3 4 5 6 7 8 9 10 |
all: gcc -c tcpsed.c ar cr libtcpsed.a tcpsed.o gcc -c tcpreceive.c ar cr libtcpreceive.a tcpreceive.o gcc -o server server.c -L. -ltcpreceive -lpthread gcc -o client client.c -L. -ltcpsed -lpthread clean: rm -rf *.o *.a server client |
微信扫一扫,关注我!
时间: 2024-10-10 22:03:20