并发服务器的实现

一、服务器端:tcpserv01.c

/*************************************************************************
    > File Name: tcpserv01.c
    > Author: zsj
    > Mail: 15623582731.com 
    > Created Time: 2017年08月07日 星期一 16时17分55秒
 ************************************************************************/


#include<unp.h>

int main()
{
int listenfd,connfd;  //创建监听,连接套接字。
pid_t childpid;  //创建子进程。
socklen_t clilen;//定义套接字的长度。

struct sockaddr_in cliaddr,servaddr;//定义 客户 与服务器套接字

listenfd=Socket(AF_INET,SOCK_STREAM,0);//监听套接字
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;//IPV4协议
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);//返回32位的IP地址的网络序。
servaddr.sin_port=htons(SERV_PORT); //返回16位端口号的网络序。

Bind(listenfd,(SA*) &servaddr,sizeof(servaddr));//调用bind函数给服务器指定 一个监听接口,
和通配地址
Listen(listenfd,LISTENQ);//给监听套接字维护一个队列。
for(; ;)
{
clilen=sizeof(clilen);
connfd=Accept(listenfd,(SA*)&cliaddr,&clilen);//返回一个已连接套接字,
二三参数为客户端ip 接口,以及套接字地址长度。

if((childpid=Fork())==0)
{
  Close(listenfd);//子进程关闭监听套接字
  str_echo(connfd); //在套接字上回射数据
  exit(0);

}
Close(connfd);

}




}

 str_echo.c
#include<unp.h>

void str_echo(int sockfd)
{
ssize_t n;

char buf[MAXLINE];

again:

while((n=read(sockfd,buf,MAXLINE))>0)//read函数从套接字读取数据,

{
  Writen(sockfd,buf,n);//written函数把其中内容回射给客户。

  if(n<0 && errno==EINTR)
      goto again;

  else if(n<0)
  {
   err_sys("read error");
  }
}


}



二、客户端:tcpcli01.c

/*************************************************************************
    > File Name: tcpcli01.c
    > Author:zsj
    > Mail: 15623582731@163.com 
    > Created Time: 2017年08月07日 星期一 16时40分23秒
 ************************************************************************/

#include<stdio.h>
#include<unp.h>

int main(int argc,char **argv)
{
  int sockfd;

  struct sockaddr_in servaddr;

  if(argc!=2)
      err_quit("usag:tcpcli");

  sockfd=Socket(AF_INET,SOCK_STREAM,0);//创建一个套接字

  bzero(&servaddr,sizeof(servaddr));
  servaddr.sin_family=AF_INET;
  servaddr.sin_port=htons(SERV_PORT);//取得16位端口号的网络序
  Inet_pton(AF_INET,argv[1],&servaddr.sin_addr);//将输入的服务器IP地址转换成二进制。

  Connect(sockfd,(SA*)&servaddr,sizeof(servaddr));//建立与服务器的连接。

  str_cli(stdin,sockfd);

  exit(0);
}


/*************************************************************************
    > File Name: str_cli.c
    > Author: zsj
    > Mail: 15623582731@163.com 
    > Created Time: 2017年08月07日 星期一 16时48分38秒
 ************************************************************************/

#include<stdio.h>
#include<unp.h>

void str_cli(FILE *fp,int sockfd)
{
  char sendline[MAXLINE] ,recvline[MAXLINE];

  while(Fgets(sendline,MAXLINE,fp)!=NULL)
  {
    Writen(sockfd,sendline,strlen(sendline));
    if(Readline(sockfd,recvline,MAXLINE)==0)
        err_quit("str_cli");

    Fputs(recvline,stdout);


  }


}

三、程序测试:

zsj@zsj-virtual-machine:~/unp/code$ tcpserv01
[1] 17798

zsj@zsj-virtual-machine:~/unp/code$
netstat -a
激活Internet连接 (服务器和已建立连接的)
(1)打开 服务器后:9877是服务器端接口,处于监听状态。

tcp 0 0 :9877 :* LISTEN

(2)开启客户端与服务器建立连接

./tcpcli01 127.0.0.1

roto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:56121 localhost:9877 ESTABLISHED //客户端子进程套接字
tcp 0 0 localhost:9877 localhost:56121 ESTABLISHED //服务器子进程套接字
tcp 0 0 :9877 :* LISTEN //监听套接字

(3)键入一行,立即得到回射接着终止客户,立即执行

netstat -a

tcp 0 0 :9877 :* LISTEN
cp 0 0 localhost:56122 localhost:9877 TIME_WAIT

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值