zoukankan      html  css  js  c++  java
  • unix网络编程 TCP客户/服务器程序

    一、创建进程经常会用到的进程号类型(在linux下)

    1.pid_t:这个类型实际上定义也是int型(是宏定义的unsigned int)

    二、bzero()函数

    用法:#include<string.h>

    功能:置字节字符串s的前n个字节 为0且包括“”

    函数原型:void bzero(void *s,int n)

    s为内存(字符串)指针,n为需要清零的字节数,bzero()会将参数s所指的内存区域前n个字节,全部设为零值。

    三、htonl()函数

    功能:将一个32位数从主机字节顺序转换成网络字节顺序

    返回值:htonl()返回一个网络字节顺序的值

    在linux系统下:

    #include<arpa/inet.h>

    uint32_t htonl(uint32_t hostlong);

    (有些系统包含的头文件是<netinet/in.h>而不是<arpa/inet.h>)

    四、TCP回射服务器程序——main函数

    #include "unp.h"
    int
    main(int argc,char **argv)
    {
       int listenfd,connfd;
       pid_t  childpid;
       socklen_t clilen;
       
       /*c语言中的结构体类型,类型名为sockaddr_in*/
       struct sockaddr_in cliaddr,servaddr;
       
       //socket函数指明调用的协议族.该过程为创建TCP套接字,socket函数创建一个网际(AF_INET)字节流(SOCK_INET)套接字,该函数返回整数描述符
       listenfd=socket(AF_INET,SOCK_STREAM,0);
       
       //将网际套接字结构清零
       bzero(&servaddr,sizeof(servaddr));
       
       //声明服务器的协议族
       servaddr.sin_family=AF_INET;
       
       //在套接字地址结构中填入通配地址(INADDR_ANY),把命令行参数转换为合适的格式
       servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
       
       //在套接字地址结构中填入服务器的众所周知端口(SERV_PORT),调用htons转换二进制端口号,由主机字节顺序为网络字节顺序
       servaddr.sin_port=htons(SERV_PORT);
       
       //bind函数把本协议的地址赋予一个套接字
       bind(listenfd,(SA*)&servaddr,sizeof(servaddr));
       
       //改变套接字的状态,把套接字变成监听套接字
       listen(listenfd,LISTENQ);
      
       for( ; ; )
       {
         clilen=sizeof(cliaddr);//记录下客户的地址长度
         connfd=accept(listenfd,(SA*)&cliaddr,&clilen);//接收客户发来的消息
         if((childpid=fork())==0)//创建子进程
        { close(listenfd);//创建成功,关闭监听
          str_echo(connfd); //处理应答,子进程继续调用套接字
          exit(0);
         }
         close(connfd);//父进程停止连接套接字
         }
    }

    五、ssize_t类型

    什么是size_t类型? 为了增强程序的可以移植性。不同系统上,size_t可能不一样。size一般表示一种计数。意义是:计量内存中克容纳的数据项目个数的无符号整数类型。

    ssize_t:表示可以被执行读取操作的数据块大小。

    六、TCP回射服务器程序——str_echo函数

    #include"unp.h"
    void
    str_echo(int sockfd)//str_echo:从客户读入数据,并把它们回射给客户
    {
       ssize_t n;//写下长度
       char buf[AXLINE];
    again://一种循环,和goto again一起用
       while((n=read(sockfd,buf,MAXLINE))>0)//从套接字读入数据
        Writen(sockfd,buf,n);//把sockfd的内容写到buf回射给客户
       
      if(n<0&&errno==EINTR)//失败再重复一次
        goto again;
      else if(n<0)//彻底失败
         err_sys("str_echo:read error");
    }

    七、TCP回射客户程序:main函数

    #include "unp.h"
    int
    main(int argc,char **argv)
    {
       int sockfd; 
       struct sockaddr_in servaddr;
       if(argc!=2)
         err_quit("usage:tcpcli <IPaddress>");
       
       //创建TCP套接字,用服务器IP地址和端口号装填一个网际网套接字地址结构
      sockfd=socket(AF_INET,SOCK_STREAM,0);
    
       //我们可以从命令行参数取得服务器的IP地址,从头文件unp.h获取服务器众所周知端口连接服务器
       //把服务器的众所周知端口捆绑到套接字
       bzero(&servaddr,sizeof(servaddr));
       
       servaddr.sin_family=AF_INET;
       servaddr.sin_port=htons(SERV_PORT);
       inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
       
       connect(sockfd,(SA*)&servaddr,sizeof(servaddr)); //connect建立与服务器的连接
       str_cli(stdin,sockfd);//完成剩余部分的客户处理工作
       exit(0);
    }

    八、TCP回射客户程序:str_cli函数

    str_cli函数完成客户处理循环:从标准输入读入一个文本,写到服务器上,读回服务器对该行的回射,并把回射行写到标准输出上

    #incldue  "unp.h"
    void
    str_cli(FILE *fp,int sockfd)
    {
       char sendline[MAXLINE],recvline[MAXLINE];
       while(fgets(sendline,MAXLINE,fp)!=NULL)
       //读入一行文本,writen把该行发送到服务器
       //当遇到文件结束符或错误时,fgets将返回一个空指针,于是客户处理循环终止
       //fgets包裹检查是否发生错误,若发生则中止进程
       //fgets只是在遇到文件结束符时才返回一个空指针
       {
        write(sockfd,sendline,strlen(sendline));
        if(readline(sockfd,recvline,MAXLINE)==0)//从服务器读入回射行,fputs把它写到标准输出
        err_quit("str_cli:server terminated prematurely");
        fputs(recvline,stdout);//把回射行写在标准输出
        }
    }

    九、回射程序结构体与结构体所对应的头文件(在c语言的环境下)

    结构体/语句/函数 头文件 作用
    exit(0) #include<stdlib.h> 在子进程终结程序,程序正常退出
    exit(-1)/exit(1) #include<stdlib.h> 在子进程终结程序,程序异常退出

    struct sockaddr_in

    #include<netinet/in.h>或#include<arpa/inet.h> 处理网络通信的地址
    socket() #include<sys/types.h>或#include<sys/socket.h> 创建套接字
    bind() #include<sys/types.h>或#include<sys/socket.h> 绑定本机端口
    connect() #include<sys/types.h>或#include<sys/socket.h> 建立连接
    listen() #include<sys/socket.h> 监听端口
    accept()

    #include<sys/types.h>或#include<sys/socket.h>

    建立连接

    十、sockaddr_in结构体

    有两个结构体,sockaddr和sockaddr_in。sockaddr的缺陷是不能把目标地址和端口号分开,而sockaddr_in能够把port(端口号)和addr(地址)分开

    服务器/客户程序正常连接

    防火墙 (firewalld)服务开启、关闭、重启、状态查看:

    启动:# systemctl start  firewalld

    查看状态:# systemctl status firewalld 或者 firewall-cmd –state(常用)

    停止:# systemctl disable firewalld

    禁用:# systemctl stop firewalld(常用)

    重启:#systemctl restart firewalld

    用alias命令简化别名的用法

    alias命令用来设置指令的别名

    作用:我们可以使用该命令可以将一些较长的命令进行简化。

    alias 旧命令=‘新命令 选项 参数’

    查看所有已设置的别名

    alias -p

    取消别名

    unalias (我们设置的命令)

     正常情况下我们简化的命令只在当前shell有效,若要在所有情况下都能够使用,就需要配置到/etc/bashrc文件当中

    怎么配置到环境变量中?

    1. 先在命令行界面完成上述简化过程
    2. 然后以root的身份打开vim ~/.bashrc,并把我们上述命令复制到文件中
    3. 回到命令行界面,输入source .bashrc,完成
  • 相关阅读:
    触发器
    数据库一键退出脚本
    集合
    Android 自定义控件之继承ViewGroup创建新容器
    web学习测试环境
    ref:ubuntu下如何批量修改文件后缀名
    ref:Adding AFL Bloom Filter to Domato for Fun
    ref:phpstorm配置远程调试(xdebug)(docker中)
    ref:PHP反序列化漏洞成因及漏洞挖掘技巧与案例
    ref:【干货分享】PHP漏洞挖掘——进阶篇
  • 原文地址:https://www.cnblogs.com/181118ljh123/p/12002310.html
Copyright © 2011-2022 走看看