搭建tcp服务器

 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<netinet/in.h>
  4 #include<netinet/ip.h>
  5 #include<sys/socket.h>
  6 #include<stdlib.h>
  7 #include<unistd.h>
  8 #include<string.h>
  9 #include<arpa/inet.h>
 10 #include<fcntl.h>
 11 #include<sys/stat.h>
 12 
 13 int main(int argc, const char *argv[])
 14 {
 15     //选择外部传参
 16     if(argc<3)
 17     {
 18         fprintf(stderr,"请输入IP和端口\n");
 19         return -1;
 20     }
 21     //将外部传参的端口号字符串,转化成整形
 22     int port=atoi(argv[2]);
 23     //填充服务器的IP和端口号-->因为客户需要主动发数据包给服务器 
 24     //创建报式套接字
 25     int sfd=socket(AF_INET,SOCK_DGRAM,0);//udp模式
 26     if(sfd<0)
 27     {
 28         perror("sfd");
 29         return -1;
 30     }
 31     //定义用来接受服务器的IP和地址寻找服务器用
 32     struct sockaddr_in sin;
 33     sin.sin_family = AF_INET;
 34     sin.sin_port = htons(port);
 35     sin.sin_addr.s_addr=inet_addr(argv[1]);
 36 
 37     struct sockaddr_in cin;//这里指的要存储的数据包
 38     socklen_t len=sizeof(cin);
 39     char data[50]="";
 40     char *ptr=data;
 41     short *sh=(short*)data;
 42     *sh=htons(1);
 43     char *pb=ptr+2;
 44     strcpy(pb,"5.png");
 45     char *pc=pb+strlen(pb);
 46     *pc=0;
 47     strcpy(pc+1,"octet");
 48     //计算数组实际占用字符大小
 49     int size=2+strlen("5.png")+1+strlen("octet")+1;
 50     printf("siz=%d\n",size);    
 51     if(sendto(sfd,data,size,0,(struct sockaddr*)&sin,sizeof(sin))<0)
 52     {
 53         perror("sendto");
 54         return -1;
 55     }
 56     printf("sendto success\n");
 57     char buf[516]="";//数据包接收
 58     char ack[5]="";
 59     short *ak;
 60     int res=0;//接收返回的字节数
 61     short num=1;
 62     int fd=open("./1.png",O_WRONLY|O_CREAT,0664);//打开一个写入文件
 63     if(fd<0)
 64     {
 65         perror("open");
 66         return -1;
 67     }
 68     while(1)//循环
 69     {   
 70         //接收服务器发来数据包,谁发来的,我发给谁
 71         bzero(buf,sizeof(buf));
 72         bzero(ack,sizeof(ack));
 73         res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
 74         if(0<res||res<=516)
 75         {
 76             write(fd,buf+4,res-4);
 77             printf("res=%d\n",res);
 78             if(res<516){
 79                 printf("数据读取完毕\n");
 80                 break;
 81             }
 82 
 83         }
 84         else if(res<0){
 85             perror("reveform");
 86             close(sfd);
 87             return -1;
 88         }   
 89         short *bh=(short*)buf;//强转short型
 90         *bh=htons(3);//将所有的操作码数据包的全部转为3
 91         ptr=buf;//指针指向数组
 92         if(ntohs(*(short*)(buf+2))!=num)
 93         {
 94             continue;//如果该数据包不是所需要的数据包,重新获取
 95         }
 96 
 97         printf("buf=%hd\n",ntohs(*(short*)(buf+2)));
 98         ak=(short*)ack;//定义ack操作码
 99         *ak=htons(4);//将ack码恒定位4
100         *(short*)(ack+2)=htons(num);//将块编号赋值给ack块编号
101 
102         printf("%hd\n",ntohs(*(short*)(ack+2)));
103         //bzero(ack,sizeof(ack));
104         if(sendto(sfd,ack,4,0,(struct sockaddr*)&cin,sizeof(cin))<0)
105         {
106             perror("sendto");
107             return -1;
108         }
109         num++;//完成一次数据收发编号增加一次;
110     }
111     //关闭套接字
112     close(sfd);
113     return 0;
114 }
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值