关于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