网络编程

socket三类型
    流式套接字(SOCK_STREAM)使用 TCP协议
    数据报套接字(SOCK_DGRAM) 数据报协议UDP,相互独立报文传输
            无序的,不保证可靠,无差错。
    原始套接字(SOCK_RAW)允许使用 IP协议,用于新网络协议测试

struct sockaddr{        //记录IP地址
    u_short sa_family;    //指定哪个协议的地址
    char sa_data[14];    //14字节的特定协议地址
}

struct sockaddr_in{            //记录网络地址, 通常使用这个
    short int sin_family;        //    协议族 AF_INET 
    unsigned short int sin_port;    //    端口号
    struct in_addr sin_addr;        //    协议特定地址
    unsigned char sin_zero[8];    //填0
}

            typedef struct in_addr{
                union{
                    struct{
                                unsigned char s_b1,s_b2,s_b3,s_b4
                                }S_un_b;
                    struct{
                                unsigned short s_w1,s_w2
                                }S_un_w;
                      unsigned long s_addr;
                        }S_un;
            }IN_ADDR;

将网络地址转换成常用的1.0.0.1形式
int inet_aton(const char*cp,struct in_addr*inp)
char *inet_ntoa(struct in_addr in)
a代表ascii,n代表network

网络字节序(big endian大端)低字节先传输

htons     发送前使用
    把unsigned short 类型从主机序转换到网络序
htonl     发送前使用
    把unsigned long类型从主机序转换到网络序
ntohs
    把unsigned short类型从网络序转换到主机序
ntohl
    把unsigned long类型从网络序转换到主机序

struct hostent*gethostbyname(const char*hostname)

struct hostent
{
    char *h_name;    //主机正式名称
    char *h_aliases;    //主机别名
    int h_addrtype;    //主机地址类型    AF_INET
    int h_length;        //主机地址长度
    char **h_addr_list;//主机IP地址列表
}

#define h_addr h_addr_list[0]    //主机的第一个IP地址


编程函数
socket    创建一个socket
bind    用于绑定IP地址和端口号到socket
connect    该函数用于与服务器建立连接
listen    设置服务器能处理的最大连接要求
accept    用来等待来自客户端的socket连接请求
send    发送数据
recv    接收数据

TCP网络程序设计
      基于TCP-服务器
    1.创建一个socket, 用函数socket()
   if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4;SOCK_STREAM:TCP
    2.   绑定IP地址、端口等信息到socket上, 用函数bind()
     if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) 
    3.设置允许的最大连接数, 用函数listen()
     if(listen(sockfd,5)==-1) 
    4.等待来自客户端的连接请求, 用函数accept()
     if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
          {
             fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
             exit(1);
          }
    5.收发数据,用函数 send()和recv(),或者read()和write()
        if((nbytes=read(new_fd,buffer,1024))==-1)
          {
              fprintf(stderr,"Read Error:%s\n",strerror(errno));
              exit(1);
          }
    6.关闭网络连接
          close(new_fd);
          close(sockfd);

      基于TCP-客户端
    1.创建一个socket,用 函数socket()
    2.设置要连接的服务器的IP地址和端口等属性
    3.连接服务器,用函数 connect()
    4.收发数据,用函数 send()和recv(),或者read()和write()
    5.关闭网络连接
   


基于UDP-服务器
1.创建一个socket(),用函数socket()
2.绑定IP地址,端口等信息到socket上
3.循环接收数据,用函数recvfrom()
4.关闭网络连接。

基于UDP-客户端
1.创建一个socket(),用函数socket()
2.绑定IP地址、端口等信息到socket上,用函数bind()
3.设置对方的IP地址和端口等属性
4.发送数据,用函数sendto()
5.关闭网络连接


服务器模型
  • 循环服务器
            同一时刻只能响应一个客户端的请求

  • 并发服务器
            同一时刻可以响应多个客户端的请求

UDP循环服务器
    socket(...);
    bind(...);
    while(1)
    {
        recvfrom(...);
        process(...);
        sendto(...);
    }

TCP循环服务器     一次只能处理一个客户端的连接。
    socket(...);
    bind(...);
    listen(...);
    while(1)
    {
        accept(...);
        process(...);
        close(...);
    }

    TCP并发服务器
    每个客户机的请求不由服务器直接处理,而是由服务器创建一个子进程
    来处理
        socket();
        bind();
        listen();
        while(1)
            {
                accept();
                if(fork(..)==0)
                        {
                            process();
                            close();
                            exit();
                        }
                close();
            }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值