开放原子开发者工作坊 Linux下TCP网络服务器实现源代码

Linux下TCP网络服务器实现源代码

大家都知道各类网络服务器程序的编写步骤,并且都知道网络服务器就两大类:循环服务和并发服务。这里附上源代码来个小结吧。首先,循环网络服务器编程实现的步骤是这样的:这种服务器模型是典型循环服务,如果不加上多进程/线程技术,此种服务吞吐量有限,大家都可以看到,如果前一个连接服务数据没有收发完毕后面的连接没办法处理。所以一般有多进程技术,对一个新连接启用一个新进程去...

 大家都知道各类网络服务器程序的编写步骤,并且都知道网络服务器就两大类:循环服务和并发服务。这里附上源代码来个小结吧。

首先,循环网络服务器编程实现的步骤是这样的:

这种服务器模型是典型循环服务,如果不加上多进程/线程技术,此种服务吞吐量有限,大家都可以看到,如果前一个连接服务数据没有收发完毕后面的连接没办法处理。所以一般有多进程技术,对一个新连接启用一个新进程去处理,而监听socket继续监听。

/************关于本文档********************************************
*filename:Linux下各类TCP网络服务器的实现源代码
*purpose:记录Linux下各类tcp服务程序源代码
*wroteby:zhoulifa(zhoulifa@163.com)周立发(http://zhoulifa.bokee.com)
Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言
*datetime:2006-07-0422:00:00
*Note:任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
*但请遵循GPL
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
*********************************************************************/

一个循环TCP服务源代码(因为用fork进行多进程服务了,所以这种服务现实中也有用)如下:

/*----------------------源代码开始--------------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
/*********************************************************************
*filename:cycletcpserver.c
*purpose:循环tcp服务端程序
*tidiedby:zhoulifa(zhoulifa@163.com)周立发(http://zhoulifa.bokee.com)
Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言
*datetime:2006-07-0422:00:00
*Note:任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
*但请遵循GPL
*Thanksto:Google.com
*********************************************************************/

intmain(intargc,char**argv)
{
int sockfd, new_fd;/*监听socket:sock_fd,数据传输socket:new_fd*/
struct sockaddr_in my_addr;/*本机地址信息*/
struct sockaddr_in their_addr;/*客户地址信息*/
unsigned int sin_size,myport,lisnum;

if(argv[1])

myport=atoi(argv[1]);
else

myport=7838;

if(argv[2])

lisnum=atoi(argv[2]);
else

lisnum=2;

if((sockfd=socket(PF_INET,SOCK_STREAM,0))==-1){
perror("socket");
exit(1);
}
my_addr.sin_family=PF_INET;
my_addr.sin_port=htons(myport);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),0);
if(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1){
perror("bind");
exit(1);
}

if(listen(sockfd,lisnum)==-1){
perror("listen");
exit(1);
}
while(1){
sin_size=sizeof(structsockaddr_in);
if((new_fd=accept(sockfd,(structsockaddr*)&their_addr,&sin_size))==-1){
perror("accept");
continue;
}
printf("server:gotconnectionfrom%s\n",inet_ntoa(their_addr.sin_addr));
if(!fork()){/*子进程代码段*/
if(send(new_fd,"Hello,world!\n",14,0)==-1){
perror("send");
close(new_fd);
exit(0);
}
}
close(new_fd);/*父进程不再需要该socket*/
waitpid(-1,NULL,WNOHANG);/*等待子进程结束,清除子进程所占用资源*/
}
}
/*----------------------源代码结束--------------------------------------------*/

一个测试客户端代码如下:

/*----------------------源代码开始--------------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#defineMAXDATASIZE100/*每次最大数据传输量*/
/*********************************************************************
*filename:cycletcpclient.c
*purpose:循环tcp客户端程序
*tidiedby:zhoulifa(zhoulifa@163.com)周立发(http://zhoulifa.bokee.com)
Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言
*datetime:2006-07-0422:20:00
*Note:任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
*但请遵循GPL
*Thanksto:Google.com
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
*********************************************************************/

intmain(intargc,char*argv[])
{
intsockfd,numbytes;
charbuf[MAXDATASIZE];
structhostent*he;
structsockaddr_intheir_addr;
unsignedintmyport;

if(argv[2])myport=atoi(argv[2]);
elsemyport=7838;

if(argc!=3){
fprintf(stderr,"usage:%shostnameport\n",argv[0]);
exit(1);
}
if((he=gethostbyname(argv[1]))==NULL){
herror("gethostbyname");
exit(1);
}
if((sockfd=socket(PF_INET,SOCK_STREAM,0))==-1){
perror("socket");
exit(1);
}
their_addr.sin_family=PF_INET;
their_addr.sin_port=htons(myport);
their_addr.sin_addr=*((structin_addr*)he->h_addr);
bzero(&(their_addr.sin_zero),0);
if(connect(sockfd,(structsockaddr*)&their_addr,sizeof(structsockaddr))==-1){
perror("connect");
exit(1);
}
if((numbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1){
perror("recv");
exit(1);
}
buf[numbytes]=0;
printf("Received:%s\n",buf);
close(sockfd);
return0;
}
/*----------------------源代码结束--------------------------------------------*/

用gcccycletcpserver.c-otcpserver和gcccycletcpclient.c-otcpclient分别编译上述代码后运行情况如下:
服务端运行显示:

administrator@ubuzlf:/data/example/c$./tcpserver
server:gotconnectionfrom127.0.0.1
server:gotconnectionfrom127.0.0.1
server:gotconnectionfrom127.0.0.1

客户端运行显示:

administrator@ubuzlf:/data/example/c$./tcpclient127.0.0.17838
Received:Hello,world!

administrator@ubuzlf:/data/example/c$./tcpclient127.0.0.17838
Received:Hello,world!

administrator@ubuzlf:/data/example/c$./tcpclient127.0.0.17838
Received:Hello,world!

转载于:https://blog.51cto.com/no001/489905

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐

  • 浏览量 102
  • 收藏 0
  • 0

所有评论(0)

查看更多评论 
已为社区贡献14条内容