Linux高性能服务器之Linux网络编程基本API实验(7)

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 Linux高性能服务器之Linux网络编程基本API实验(7),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

关于listen参数backlog实际影响

#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
static bool stop=false;
static void handle_term(int sig)
{
    stop=true;

}
int main(int argc,char* argv[])
{
    signal(SIGTERM,handle_term);.//ctrl+c 阻止 while运行
    if(argc<=3)
    {
    //、path为".","/", ".."或者为不带有/的字符串时, 输出与path一致,
    //最后一个 字符为/,输出为空;否则返回的是最后/后面的字符串
        printf("usage: %s ip_address port_number backlog\n",
               basename(argv[0]));
        return 1;
    }
    const char* ip=argv[1];
    int port=atoi(argv[2]);//char->int;
    int backlog=atoi(argv[3]);
    
    int sock=socket(PF_INET,SOCK_STREAM,0);
    assert(sock>=0);

    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family=AF_INET;//pro
    inet_pton(AF_INET,ip,&address.sin_addr);//ip;
    address.sin_port=htons(port);
    
    int ret=bind(sock,(struct sockaddr*)&address,sizeof(address));
    assert(ret!=-1);

    ret=listen(sock,backlog);
    assert(ret!=-1);
    while(!stop)
    {
        sleep(1);
    }
    close(sock);
    return 0;

}
结论为:可见,在监听队列中,处于ESTABLISHED状态的连接只有6(backlog值加1),
其他的连接都处于SYN_RCVD状态。我们改变服务器程序的第3个参数并重新运行之,
能发现同样的规律,即完整连接最多有(backlog+1)个。在不同的系统上,
运行结果会有些差别,不过监听队列中完整连接的上限通常比 backlog 值略大。

mode
argv[1] :ip
argv[2]:port

struct sockaddr_in(ipv4);
sockaddr.sin_family
sockaddr.sin_addr(inet_pton)
sockaddr.sin_port=htons();

sock
bind(sock,address,sizeof)
listen();
accept

client端

检验一个异常连接

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<errno.h>
#include<libgen.h>
#include<unistd.h>
#include<assert.h>

int main(int argc,char* argv[])
{
    if(argc<=2)
    {
        printf("Usage %s ip_address port_number\n",basename(argv[0]));
        return 1;
    }
    char* ip=argv[1];
    int port=atoi(argv[2]);

    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family=AF_INET;
    address.sin_port=htons(port);
    inet_pton(AF_INET,ip,&address.sin_addr);

    int sockfd=socket(PF_INET,SOCK_STREAM,0);
    assert(sockfd!=-1);

    int ret=bind(sockfd,(struct sockaddr*)&address,sizeof(address));
    assert(ret!=-1);
     
    ret=listen(sockfd,5);
    assert(ret!=-1);
    
    sleep(20);
    struct sockaddr_in client;
    socklen_t client_len=sizeof(client);
    int connfd=accept(sockfd,(struct sockaddr*)&client,&client_len);
    if(connfd<0)
    {
     printf("error is: %d\n",errno);
    }
    else
    {
        char remote[INET_ADDRSTRLEN];
        printf("connect with ip: %s and port :%d",inet_ntop(AF_INET,(struct 
        sockaddr*)&client,remote,INET_ADDRSTRLEN),ntohs(client.sin_port));
        close(connfd);
    }
    close(sockfd);
    return 0;




     
} 

listen-》
accept(发起连接 并且保留sockfd)-
结论:
./a.out 192.168.179.192 12345
connect with ip: 2.0.139.28 and port :35612

telnet 192.168.179.192 12345
Trying 192.168.179.192...
Connected to 192.168.179.192.
Escape character is .
Connection closed by foreign host.

netstat -nt|grep 12345
tcp        0      0 192.168.179.192:12345   192.168.179.192:35612   TIME_WAIT  
由此可见,accept 只是从监听队列中取出连接,而不论连接处于何种状态(TIME_WAIT),更不关心任何网络状况的变化。

TCP读写数据

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<libgen.h>
#include<assert.h>
int main(int argc,char* argv[])
{
    if(argc<=2)
    {
        printf("usage: %s ip_address port_number\n",basename(argv[0]));
        return 1;
    }
    const char* ip=argv[1];
    int port=atoi(argv[2]);

    struct sockaddr_in server_address;
    bzero(&server_address,sizeof(server_address));
    server_address.sin_family=AF_INET;
    server_address.sin_port=htons(port);
    inet_pton(AF_INET,ip,&server_address.sin_addr);

    int sockfd=socket(PF_INET,SOCK_STREAM,0);
    assert(sockfd>=0);
    
    if(connect(sockfd,(struct sockaddr*)&server_address,
               sizeof(server_address))<0)
    {
        printf("connection failed\n");

    }
    else
    {
        const char* obb_data="abc";
        const char* normal_data="123";
        send(sockfd,normal_data,strlen(normal_data),0);
        send(sockfd,obb_data,strlen(obb_data),MSG_OOB);
        send(sockfd,normal_data,strlen(normal_data),0);

    }
    close(sockfd);
    return 0;
}

#include<sys/socket.h>                                                      
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
 #include<unistd.h>
 #include<string.h>
 #include<stdlib.h>
 #include<libgen.h>
 #include<assert.h>
#include<errno.h>
#define BUf_SIZE 1024

int main(int argc,char* argv[])
{
    if(argc<=2)
    {
        printf("usage %s ip_address, port_number\n",basename(argv[0]));
        return 1;
    }
    const char* ip=argv[1];
    int port=atoi(argv[2]);

    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family=AF_INET;
    inet_pton(AF_INET,ip,&address.sin_addr);
    address.sin_port=htons(port);

    int sockfd=socket(PF_INET,SOCK_STREAM,0);
    assert(sockfd>0);

    int ret=bind(sockfd,(struct sockaddr*)&address,sizeof(address));
    assert(ret!=-1);

    ret=listen(sockfd,5);
    assert(ret!=-1);

    struct sockaddr_in client_address;
    socklen_t client_length=sizeof(client_address);
    int connfd=accept(sockfd,(struct sockaddr*)&client_address,&client_length);
    if(connfd<0)
    {
        printf("error is :%d\n",errno);
    }
    else
    {
     char buffer[BUf_SIZE];
     memset(buffer,'\0',BUf_SIZE);
     ret=recv(connfd,buffer,BUf_SIZE-1,0);
     printf("got %d, bytes of normal data %s\n",ret,buffer);
     
     memset(buffer,'\0',BUf_SIZE);
         ret=recv(connfd,buffer,BUf_SIZE-1,0);
        printf("got %d, bytes of normal data %s\n",ret,buffer);


        memset(buffer,'\0',BUf_SIZE);
  ret=recv(connfd,buffer,BUf_SIZE-1,0);
     printf("got %d, bytes of normal data %s\n",ret,buffer);
       
     close(connfd);
    }
    close(sockfd);
    return 0;
}

server mode:
  struct sockaddr_in address;
  socket
  bind
  listen
  accept
  recv
client:
 struct sockaddr_in address;
  socket
  connect
现象:
[root@192 netsys] ./server  127.0.0.1 6000
got 5, bytes of normal data 123ab
got 3, bytes of normal data 123
got 0, bytes of normal data 

./client 127.0.0.1 6000

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129713.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!