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