网络编程

来源:互联网 发布:app软件著作权范本 编辑:程序博客网 时间:2024/04/28 18:38
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();
            }
原创粉丝点击