- // select 实现
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h> //basic system dada types
- #include <sys/socket.h> //basic socket definitions
- #include <netinet/in.h> //sockaddr_in and other defination
- #include <arpa/inet.h> //inet(3)functions
- #include <sys/select.h> //select functions
- #define maxline 1024
- void handle(int *clientsockfd, int maxfd, fd_set *rset, fd_set *pallset);
- int main(int argc, char **argv)
- {
- int servport = 6887;
- int listeng = 1024;
- int listenfd, connfd;
- struct sockaddr_in cliaddr, servaddr;
- socklen_t socklen = sizeof(struct sockaddr_in);
- int nread, nready;
- int opt = 1;
- int i;
- char buf[maxline] = {0};
- int client_sockfd[maxline];
- fd_set allset, rset;
- int maxfd;
- listenfd = socket(AF_INET, SOCK_STREAM, 0);
- if (listenfd < 0)
- {
- perror("socket");
- return 1;
- }
-
- if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
- {
- perror("setsockopt");
- return 1;
- }
- // 配置服务器网络参数
- cliaddr.sin_family = AF_INET;
- cliaddr.sin_port = htons(servport);
- cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- bzero(cliaddr.sin_zero,8);
-
- if (bind(listenfd, (struct sockaddr *)&cliaddr, socklen) < 0)
- {
- perror("bind ");
- return 1;
- }
- if (listen(listenfd, listeng) < 0)
- {
- perror("listen");
- return 1;
- }
- printf("listening...\n");
- printf("max connection :%d\n", FD_SETSIZE);
- // 初始化文件描述符集
- FD_ZERO(&allset);
- FD_SET(listenfd, &allset);
- maxfd = listenfd;
- // 将clientsockfd【】全部赋值为-1
- for (i = 0; i < maxline; i++)
- client_sockfd[i] = -1;
- printf("echo server use select startup ,listen on port %d\n",servport);
-
- while(1)
- {
- rset = allset;
- if (select(maxfd+1, &rset, NULL, NULL, NULL) < 0)
- {
- perror("select");
- continue;
- }
- if (FD_ISSET(listenfd, &rset))
- {
- connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen);
- if (connfd < 0)
- {
- perror("accept");
- continue;
- }
- printf("connect success from %s\n",inet_ntoa(cliaddr.sin_addr));
-
- for (i = 0; i < maxline; i++)
- if (client_sockfd[i] == -1)
- {
- client_sockfd[i] = connfd;
- break;
- }
-
- if (FD_SETSIZE == i)
- {
- fprintf(stdout, "connection to many,more than %d\n",FD_SETSIZE);
- close(connfd);
- continue;
- }
- maxfd = connfd > listenfd ? connfd:listenfd;
-
- FD_SET(connfd, &allset);
- }
- handle(client_sockfd, maxfd, &rset, &allset);
- sleep(1);
- }
- return 0;
- }
- void handle(int *clientsockfd, int maxfd, fd_set *rset, fd_set *allset)
- {
- int nread;
- int i;
- char buf[maxline]={0};
- for (i = 0; i < maxfd; i++)
- {
- if (clientsockfd[i] != -1)
- {
- if (FD_ISSET(clientsockfd[i], rset))
- {
- nread = read(clientsockfd[i], buf, maxline);
- if (nread < 0)
- {
- perror("read");
- close(clientsockfd[i]);
- FD_CLR(clientsockfd[i],allset);
- clientsockfd[i] = -1;
- continue;
- }
- else if (nread == 0)
- {
- printf("client close the connection\n");
- close(clientsockfd[i]);
- FD_CLR(clientsockfd[i], allset);
- clientsockfd[i] = -1;
- continue;
- }
- printf("recive %s \n",buf);
- write(clientsockfd[i], buf, nread);
- }
- //printf("recive %s \n",buf);
- //write(clientsockfd[i], buf, nread);
- }
- }
- }
- // 多线程pthread
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/types.h> //select
- #include <sys/time.h> //select
- #include <sys/select.h> //select
- #include <unistd.h>
- #include <fcntl.h>
- #include <pthread.h>
- #include <netinet/in.h> // htonl/htons/ntohl/ntohs ...
- #define maxlen 128
- #define my_port 4525
- struct node
- {
- int n_clientfd; //保存客户端描述符
- struct sockaddr_in n_sin; //保存客户端地址信息
- struct node *n_next; //指向下一个结构体
- }*head = NULL;
- static int count; //计总共线程数
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //初始化互斥锁
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 初始化条件变量
- void cleanup_handler(void *p)
- {
- printf("pthread %d exiting...\n", count);
- //free(p);
- pthread_mutex_unlock(&mutex);
- }
- void pthread_handler(void *arg)
- {
- struct node *pnode = NULL;
- int client_fd;
- char buf[maxlen] = {0};
- char tmp[maxlen] = {0};
- int i = 10; //设置读写最大次数为10次
-
- //fd = *(int *)arg;
- pthread_cleanup_push(cleanup_handler, pnode);
-
- while(1)
- {
- pthread_mutex_lock(&mutex);//在修改head之前,锁住,保持head数据的一致性
- printf("begin to recieve data...\n");
- while(NULL == head)
- {
- pthread_cond_wait(&cond, &mutex);
- }
- pnode = head;
- client_fd = pnode->n_clientfd;
- head = pnode->n_next; //将head置为NULL
- //当不用循环时候,只能接收到一次数据,所以要用循环,不断接受数据,默认的recv。send都是阻塞的。
- while(i--) //进行10次接收数据,从客户端client_fd接收数据,并向它回发数据
- {
- if (recv(client_fd, buf, maxlen, 0) < 0) //MSG_TRUNC 即使报文被截断, 也返回报文实际长度,recv中第三个参数为报文的最大长度,会向buf指向的内存空间写maxlen的字节数,不管是否有maxlen个字节
- {
- perror("recv error");
- continue;
- }
-
- printf("recv %s from %s \n", buf, inet_ntoa(pnode->n_sin.sin_addr));
- // write data to client
- sprintf(tmp, "hello %s ,i have recv data:%s\n", inet_ntoa(pnode->n_sin.sin_addr), buf);
- send(client_fd, tmp, maxlen, 0);
- memset(buf, 0x0, maxlen);
- memset(tmp, 0x0, maxlen);
- pthread_mutex_unlock(&mutex);//shishi
- sleep(1);
- //free(pnode);
- }
- }
- pthread_cleanup_pop(0);
- }
- int main()
- {
- struct sockaddr_in addr_server, addr_client;
- char buf[maxlen] = {0};
- int server_fd, client_fd[100];
- int addr_client_size;
- pthread_t pthread_id[100] = {0};
- struct node *p;
- if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- perror("socket error");
- return -1;
- }
- // 服务器网路参数配置
- addr_server.sin_family = AF_INET;
- addr_server.sin_port = htons(my_port);
- addr_server.sin_addr.s_addr = INADDR_ANY;
- memset(addr_server.sin_zero, 0x0, 8);
- if (bind(server_fd, (struct sockaddr *)&addr_server, sizeof(addr_server)) < 0)
- {
- perror("bind error");
- return -1;
- }
- listen(server_fd, 10);
- //pthread_create(&pthread_id, NULL, (void *)pthread_handler, &client_fd); //create pthread,创建线程应该在一个循环中,在循环外,只创建了一个线程
- //在每次接到新的客户端的信息时,创建一个线程
- while(1) //开始接受来自客户端的信息,并用线程接受不同客户端的信息
- {
- count++; //计总共线程数
- if (count > 100) //客户端最大值设定为100
- {
- printf("over client number ,exiting\n");
- break;
- }
- // pthread_mutex_lock(&mutex); //
- if ((client_fd[count] = accept(server_fd, (struct sockaddr*)&addr_client, &addr_client_size)) < 0)
- {
- perror("accept error");
- continue;
- }
-
- pthread_create(&pthread_id[count], NULL, (void *)pthread_handler, NULL); //create pthread
-
- p = malloc(sizeof(struct node));
- pthread_mutex_lock(&mutex); //在向p写数据之前,锁住,保持head数据的一致性
- p->n_clientfd = client_fd[count];
- p->n_sin = addr_client;
- head = p;
- pthread_cond_signal(&cond);
- printf("the %dth times\n", count);
- pthread_mutex_unlock(&mutex);
- sleep(1);
- free(p);
- }
- printf("pthead ending--\n");
- pthread_cancel(pthread_id[count]);
- pthread_join(pthread_id[count], NULL);
- printf("exiting all pthread-------\n");
- return 0;
- }
- // fork 多用户连接的服务器
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #define max_size 1024
- #define my_port 2597
- int main()
- {
- struct sockaddr_in server_addr;
- char buf[max_size] = {0};
- int sockfd,client_fd;
- int n;
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- perror("socket");
- return 1;
- }
- bzero(&server_addr,sizeof(server_addr));
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(my_port);
- server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-
- n = 1;
- setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int));
- if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
- {
- perror("bind");
- return 1;
- }
-
- if (listen(sockfd, 5) == -1)
- {
- perror("listen");
- return 1;
- }
-
- printf("listening ...\n");
- while (1)
- {
- if ((client_fd = accept(sockfd, NULL,NULL)) == -1 && errno != EINTR)
- continue;
-
- printf("------------------\n");
- if ((n = fork()) == 0)
- {
- while (1)
- {
- if (read(client_fd, buf, max_size) == -1)
- {
- perror("recv");
- return 1;
- }
- printf("recieve data: %s\n",buf);
- memset(buf,0x0,1024);
- }
- close(client_fd);
- close(sockfd);
- exit(0);
- }
- else close(client_fd);
- }
- }
阅读(1504) | 评论(0) | 转发(0) |