• head first c<11>初探网络编程上


    server连接网络四部曲。

    为了与外界沟通,c程序用数据流读写字节。比較经常使用的数据流有标准输入、标准输出、文件等。

    假设想写一个与网络通信的程序。就须要一种新的数据流----------套接字。

     

    使用套接字与client程序通信前,server须要历经四个阶段:绑定、监听、接受、開始。

     

    1.绑定port

            计算机可能同一时候执行多个server程序。为了放置不同的对话混淆。每项服务必须使用不同的port(port)。port就好像电视频道,

    用不同的频道接受不同的节目。

            server在启动时。须要告诉操作系统将要使用哪个port,这个过程叫port绑定。为了绑定它你须要两样东西:套接字描写叙述符和套

    接字名。

    #include<sys/socket.h>
    
    int listener_d = socket(PF_INET,SOCK_STREAM,0);
    
    if (listene_d  == -1)
    
         error("无法打开套接字");
    


     


    当中listener_d为套接字描写叙述符,绑定用bind函数

     

    #include <arpa/inet.h>   //为了创建互联网地址
    
    ....
    
    struct sockaddr_in name;
    
    name.sin_family = PF_INET;
    
    name.sin_port = (in_port_t)htons(30000);            //创建一个表示互联网30000端口的套接字名
    
    name.sin_addr.s_addr =htonl(INADDR_ANY);
    
    int c = bind(listener_d,(struct sockaddr *) &name,sizeof(name));
    
    if (c == -1)
    
      error("无法绑定port");
    


     

    2.监听

    if (listen(listen_d),10) ==1)  //队列长度为10
    
     error("无法监听")。
    


     

      把队列长度设为10,也就是说最多能够有10个client同一时候尝试连接server,它们不会马上得到响应,但能够排队等候。而第十一个

    client会被告知server忙。

     

    3.接受连接

    一旦帮顶完port。设置为监听队列。唯一能够做的就是等待。

    server的一生都在等待有client来连接他们。直到有client连接server时,它会返回第二个套接字描写叙述符。然后就能够通信了。

     

    struct sockaddr_storage client_addr;  //保存连接客户端的具体信息
    
    unsigned int address_size = sizeof (client_addr);
    
    int connect_d = accept(listener_d,(struct sockaddr *)&client_addr,&address_size);
    
    if (connect_d == -1) 
    
      error("无法打开副套接字");
    


     

    server将用新的连接描写叙述符connect_d

     

    4.開始通信

    socket套接字这个数据流是双向的,既能够用作输入也能够用作输出。

    假设想向套接字输出数据。就要用send()函数。而不是fprint()

    char *msg = "xxxxxxxxxxx"
    
    if (send(connect_d,msg,strlen(msg),0) == -1)
    
     error("send")。
    


     


     

    注:怎样选择port号

    仅仅有超级用户或管理员才有资格使用1024号一下的port。由于小号的port留给了一些知名服务。如网页server和邮件server。

    操作系统仅仅同意管理员用这些port。防止普通用户启动一些多余的服务。

    因此,通常情况下请使用1024以上的port。

    绑定port有延时

          当你绑定某个port和套接字时,在接下来的30秒内。操作系统不同意不论什么程序再绑定它。包含上次绑定它的程序。这样万一你的

    服务端瞬间重新启动了一下,也没办法立马绑定那个port,造成client得不到响应。

    int reuse =1;   //须要用一个整形变量来保存选项,设为1,表示又一次使用port
    
    if (setsockopt(listener_d,SOL_SOCKET,SO_REUSEADDR,(char *)&reuse,sizeof(int)) == -1)
    
    error ("无法设置又一次使用");
    


     

    从client读数据。recv()函数

    <读了几个字节> =recv(<描写叙述符>。<缓冲区>,<要读几个字节>,0)。
    

    注:

    <1>字符串不以结尾。

    <2>在telnet输入文本时。字符串以 结尾

    <3>recv()返回字符个数,如错误发生则返回-1,假设client关闭了连接,则返回0

    <4>recv调用不一定能一次接受全部字符,它意味着可能须要多次调用recv()

    recv()用起来十分繁琐,最好把它封装在某个函数中,比方以下这个函数,它指定数组中保存以结尾的字符串

    int read_in(int socket, char *buf,int len)
    
    {
    
    char *s =buf ;
    
    int slen =len;
    
    int c =recv(socket,s,slen,0);
    
    while((c>0) && (s[c-1]!='
    '))
    
    {
    
    s +=c;
    
    slen -=c;
    
    c=recv(socket,s,slen,0);
    
    }
    
    if (c<0)
    
        return c;
    
    else if (c == 0)
    
       buf[0]='';
    
    else
    
        s[c-1]='';
    
    return len-slen。
    
    }
    


     


     


     


  • 相关阅读:
    Java 验证码工具类
    Servlet实现文件下载
    SQLyog连接报错 Error No.2058 Plugin caching_sha2_password could not be loaded
    springmvc上传文件出现异常,postman测试,文件上传问题org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;
    swaager2中实现文件上传的api测试操作
    idea中无法正常显示java与jsp文件内容
    servlet容器多线程与spring单例
    ThreadLocal使用与注意事项
    mysql的分组之后取时间最大的时间的那个数据
    servlet中常见装饰类HttpServletRequestWrapper等等
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5364938.html
Copyright © 2020-2023  润新知