Linux下IP v6 tcp服务器端源码示例

/******************************
*
* server.c
*
******************************/
#include<stdio.h>  
#include<stdlib.h>  
#include<sys/socket.h>  
#include<sys/types.h>  
#include<errno.h>  
#include<string.h>  
#include<netinet/in.h>  
#include<sys/wait.h>  
#include<unistd.h>  
#include<arpa/inet.h>  
#include<pthread.h>  
   
   
#define MAXBUF 1024  
#define LISNUM 10  
#define DEFULT_PORT 8787  
   
void *connect_to_client(void *data);  
struct sockaddr_in6 serv_addr,client_addr;  
/**************************/
int main(int argc,char *argv[])  
{  
       int sockfd,new_fd;  
       unsigned int serv_port;  
       unsigned int lisnum;  
       char buf[MAXBUF+1];  
         
       printf( "the command is %s [port] [listen_num]\n", argv[0] );  
         
       // 监听起始端口  
       if ( argv[1] != NULL )  
       {  
              serv_port = atoi( argv[1] );  
       }  
       else
       {  
              serv_port = DEFULT_PORT;  
       }  

       // 监听端口个数  
       if ( argv[2] != NULL )  
       {  
              lisnum = atoi(argv[2]);  
       }  
       else
       {  
              lisnum = LISNUM;  
       }  
         
       // 创建socket  
       if ( (sockfd = socket(PF_INET6,SOCK_STREAM,0)) < 0 )  
       {  
              perror("creat socket");  
              exit(1);  
       }  
         
       // 配置服务器地址与端口  
       bzero(&serv_addr, sizeof(serv_addr));  
       serv_addr.sin6_family = AF_INET6;  
       serv_addr.sin6_port = htons(serv_port);  
       serv_addr.sin6_addr = in6addr_any;  
       // 地址绑定操作  
       if ( bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr) ) <0 )  
       {  
              perror("bind");  
              exit(1);  
       }  
         
       // 服务器监听  
       if ( listen(sockfd, lisnum) < 0 )  
       {  
              perror("listen");  
              exit(1);  
       }  
         
       while(1)  
       {  
              int len = sizeof(struct sockaddr_in6);  
              if ( (new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &len)) < 0 )  
              {  
                     perror("accept");  
                     exit(errno);  
              }  
              printf("receive the request form %s\n", inet_ntop(AF_INET6, &client_addr, buf, sizeof(buf)));  
                
              // 接收到1个TCP连接则创建1个线程用于数据通讯  
              pthread_t child_thread;  
              if ( pthread_create( &child_thread, NULL, connect_to_client, (void *)new_fd) < 0)  
              {  
                     perror("create thread");  
                     continue;  
              }  
       }  
       close( sockfd );  
         
       return(0);  
}  

/************************************
*
* 子程序:用于处理一个与客户端的连接,由一个线程来执行
*
************************************/
void *connect_to_client(void *data)  
{  
       int i;  
       int client_fd=(int)data;  
       char recv_buf[MAXBUF+1];  
       char send_buf[MAXBUF+1];  
       char buf[MAXBUF+1];  
       while(1)  
       {  
              sprintf( send_buf, ">>" );  
              if ( send(client_fd, send_buf, strlen(send_buf), 0) < 0 )  
              {  
                     perror("send");  
                     continue;  
              }  
                
              // 从客户端接收数据,直到接收到换行符   
              while ( i < MAXBUF-1 )  
              {  
                     if ( recv(client_fd, &recv_buf[i], 1, 0) < 0 )  
                     {  
                            perror("recv");  
                            break;  
                     }  
                       
                     if ( recv_buf[i] == '\n' )  
                     {  
                            break;  
                     }  
                       
                     i++;  
              }  
                
              recv_buf[i] = '\0';  
              i = 0;  
              // 将接收到的数据输出到标准输出  
              printf("receive message from '%s':%s\n",  
                      inet_ntop(AF_INET6, &client_addr.sin6_addr, buf, sizeof(buf)),  
                      recv_buf);  
       }  
}//end sub_function