// File Name: socket.cpp
// Author: simon li
// Created Time: 2019年09月23日 星期一 17时01分07秒
#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<netinet/in.h>
#include<bits/socket.h>
#include<sys/un.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<signal.h>
#include<unistd.h>
#include<assert.h>
using namespace std;
//Linux提供了一以下4个函数来完成主机字节序和网络字节序之间的转换
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);
/*int inet_pton(int af , const char* src,void* dst);//将src的点十分禁止转换为网络字节序,并存入dst中
const char* inet_ntop(int af, const void* src, char* dst,socklen_t cnt);
//将网络字节数af转换成点分十进制的IPV4地址src到dst中
static bool stop = false;
int socket(int domain, int type,int protocol);
//创建socket。domain采用的协议:PF_INET或者PF_INET6,type 服务类型有:SOCK_STREAM和SOCK_UGRAM,
//protocol采用默认协议
int bind (int sockfd,const struct sockaddr* my_addr,socklen_t addrlen);
//命名socket,将 my_addr所指的socket地址分配给sockfd文件描述符,addrle指出该cocket地址长度
int
struct sockaddr//表示sokcet的地址的结构体
{
sa_family_t sa_family;//地址族协议类型
char sa_data[13];
};
struct sockaddr_storage//为了存储更多的协议族,
{
sa_family_t sa_family;//地址族协议类型
unsigned long int _ss_alig;
char _ss_padding[128 - sizeof(_ss_align)];
};
struct sokaddr_un//unix专用的socket地址
{
sa_family_t sin_falmily;//地址族:AF_UNIX
char sun_path[108];//文件路径
};
struct sockaddr_in//IPV4
{
sa_family_t sin_family;//地址族协议族:AF_INET
u_int16_t sin_port;//端口号:用网络字节序
struct in_addr sin_addr;//IPV4地址结构体
};
struct in_addr
{
u_int32_t s_addr;
};
struct sockaddr_in6
{
sa_family_t sin6_family;
u_int16_t sin6_port;
u_int32_t sin6_flowinfo;
struct in6_addr sin6_addr;
u_int32_t sin6_scope_id;
};
struct in6_addr
{
unsigned char sa_addr[16];
};*/
//监听socket
#include<sys/socket.h>
int listen (int sockfd,int backlog);
//sockfd参数指定被监听的socket,backlog参数提示内核监听队列的最大长度
static bool stop = false;
static void handle(int sig)//SIGTERM信号的处理函数,触发时结束住程序中的循环
{
stop = true;
}
int main(int argc,char* argv[]){
signal(SIGTERM,handle);
if (argc <= 3)
{
cout<<"usage:"<<basename(argv[0])<<"ip_address port_number backlog"<<endl;
return 1;
}
const char* ip = argv[1];//IP地址
int port = atoi(argv[2]);//端口号
int backlog = atoi (argv[3]);//内核监听队列最大长度,将字符转化成整形
int sock = socket (PF_INET,SOCK_STREAM,0);//创建socket
assert(sock >= 0);
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;//选择协议簇类型IPV4
inet_pton(AF_INET,ip,&address.sin_addr);
//点十分进制的ipv4地址转换成网络字节序证书存储与 address中
address.sin_port = htons(port);
int ret = bind(sock,(struct sockaddr*)&address,sizeof(address));//创建socket绑定IP弟子和端口号
assert(ret!= -1);
ret = listen(sock,backlog);//监听该端口的数据,并确定监听队列长度
assert(ret != -1);
while(!stop)
{
sleep(1);
}
close(sock);
return 0;
}