- 论坛徽章:
- 0
|
本帖最后由 frank529 于 2012-05-04 10:58 编辑
测试代码,服务器端,环境Linux2.6.30- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/ioctl.h>
- #include <netdb.h>
- #include <net/if.h>
- #include <netinet/in.h>
- #include <net/if_arp.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <ifaddrs.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <termios.h>
- #include <pthread.h>
- #include <netinet/tcp.h>
- #define READER_FDSIZE 10
- int client_sockfd;
- void *sendmsg_thread(void *arg)
- {
- int netcnt;
- while(1)
- {
- netcnt = send(client_sockfd,"hello client",strlen("hello client")+1,0);
- if(netcnt != strlen("hello client")+1)
- printf("netcnd = %d\n",netcnt);
- sleep(2);
- }
- }
- int main(void)
- {
- int server_sockfd;
- struct sockaddr_in server_sockaddr,client_sockaddr;
- fd_set reader_fds, error_fds;
- int res = 0;
- int sin_size;
- int nread;
- char *rcvbuffer;
- pthread_t thread_send_msg;
- int optval;
- socklen_t optlen = sizeof(optval);
- /*创建socket连接*/
- if((server_sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
- {
- perror("socket");
- server_sockfd = -1;
- goto exit;
- }
- /*enable address reuse */
- int on;
- int ret;
- on = 1;
- ret = setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- /*设置sockaddr_in 结构体中相关参数*/
- server_sockaddr.sin_family = AF_INET;
- server_sockaddr.sin_port = htons(7086);
- server_sockaddr.sin_addr.s_addr = INADDR_ANY;
- bzero(&(server_sockaddr.sin_zero),8);
- /*绑定函数bind*/
- if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))== -1)
- {
- perror("bind");
- server_sockfd = -1;
- goto exit;
- }
- /*调用listen函数*/
- if(listen(server_sockfd,10)== -1)
- {
- perror("listen");
- server_sockfd = -1;
- goto exit;
- }
- FD_ZERO(&reader_fds);
- FD_SET(server_sockfd, &reader_fds);
- while(1)
- {
- res = select(READER_FDSIZE, &reader_fds,(fd_set *)0, (fd_set *)0 , NULL);
- if(res < 0)
- perror("select");
- /* 有客户端连入 */
- if(FD_ISSET(server_sockfd, &reader_fds))
- {
- sin_size = sizeof(struct sockaddr);
- client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_sockaddr,&sin_size);
- if(client_sockfd < 0)
- {
- perror("accept");
- goto exit;
- }
- /* 开启KEEPALIVE */
- optval = 1;
- optlen = sizeof(optval);
- if(setsockopt(client_sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0)
- {
- perror("setsockopt()");
- close(client_sockfd);
- goto exit;
- }
- printf("SO_KEEPALIVE set on socket\n");
-
- /* 设置KEEPALIVE时间为1s */
- optval = 1;
- res = setsockopt(client_sockfd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen);
- if(res < 0)
- perror("setsockopt TCP_KEEPIDLE");
- /* 设置KEEPALIVE间隔为1s */
- res = setsockopt(client_sockfd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen);
- if(res < 0)
- perror("setsockopt TCP_KEEPIDLE");
- /* 设置KEEPALIVE重试次数为3次 */
- optval = 3;
- res = setsockopt(client_sockfd, SOL_TCP, TCP_KEEPCNT, &optval, optlen);
- if(res < 0)
- perror("setsockopt TCP_KEEPIDLE");
- fcntl(client_sockfd,F_SETFL,O_NONBLOCK); // 设置非阻塞
- FD_SET(client_sockfd, &reader_fds); // client_sockfd加入reader_fds
- /* 创建发送线程 */
- ret = pthread_create(&thread_send_msg, NULL, sendmsg_thread, NULL);
- continue;
- }
- if(FD_ISSET(client_sockfd, &reader_fds))
- {
- /* 如果没有发送线程,网络断连后,select会不断返回,nread一直为0;*/
- /* 有发送线程,断连后select会阻塞,不会运行到此处 */
- ioctl(client_sockfd, FIONREAD, &nread);
- if(nread <= 0)
- {
- printf("nread = %d\n",nread);
- }
- else
- {
- rcvbuffer = malloc(nread);
- res = read(client_sockfd, rcvbuffer, nread);
- if(nread > 0)
- {
- printf("receive %s\n",rcvbuffer);
- }
- free(rcvbuffer);
- }
- }
-
- }
- exit:
- return -1;
- }
复制代码 |
|