socket各个结构体及其参数

1.sockaddr_in结构体

//老的结构体
struct sockaddr{
    unsigned short sa_family;       //地址类型,AF_xxx
    char sa_data[14];               //14字节的端口和地址
}

struct sockaddr_in{
    short int sin_family;           //地址类型
    unsigned short int sin_port;    //端口号
    struct in_addr sin_addr;        //地址
    unsigned char sin_zero[8];      //为了保持与struct sockaddr一样的长度
}

struct in_addr{
    unsigned long s_addr;           //地址
}

2.gethostbyname

下面这段代码可以替换为

  if ( (h = gethostbyname(argv[1])) == 0 )   // 指定服务端的ip地址。
  { printf("gethostbyname failed.\n"); close(sockfd); return -1; }

|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/|/

servaddr.sin_addr.s_addr = inet_addr(argv[1])); // 指定ip地址。

但是gethostbyname支持域名,主机名解析。

struct hostent
{
    char *h_name;  //主机名,即官方域名
    char **h_aliases;  //主机所有别名构成的字符串数组,同一IP可绑定多个域名
    int h_addrtype; //主机IP地址的类型,例如IPV4(AF_INET)还是IPV6
    int h_length;  //主机IP地址长度,IPV4地址为4,IPV6地址则为16
    char **h_addr_list;  /* 主机的ip地址,以网络字节序存储。若要打印出这个IP,需要调用inet_ntoa()。*/
};

#define h_addr h_addr_list[0] 

/*
这里有两个socket,listen只负责客户端的连接事件
accept返回的socket是用来跟客户端通信的
*/

3. bind

小于1024的端口号通常被通用的知名端口占用了,例如http的端口是80.

3.1服务端的端口释放后可能会处于TIME_WAIT状态,等待两分钟之后才能再被使用?

//设置SO_REUSEADDR
int opt = 1;
unsigned int len = sizeof(opt);
setsockopt(listenfd, SOL_SOCKET,SO_REUSEADDR,&opt,len);

4.accept

从已准备好的连接队列中获取一个请求,如果队列为空,accept函数将阻塞

5.listen

  1. 服务端在调用listen()之前,客户端不能向服务端发起连接请求
  2. 服务端调用listen()函数后,服务端的socket开始监听客户端的连接
  3. 客户端调用connect()函数向服务端发起连接请求
  4. 在tcp底层,客户端和服务端握手后建立起通信通道,如果有多个客户端请求,在服务端就会形成一个已准备好的连接队列
  5. 服务端调用accet()函数从队列中获取一个已准备好的连接,函数返回一个新的socket,新的socket用于与客户端通信,listen的socket只负责监听客户端的连接请求

在这里插入图片描述

linux内核会为listen状态的socket维护两个队列:不完全连接请求队列(SYN_RECV状态)和等待accept建立socket的队列(ESTABLISHED状态)

TCP建立连接要三次握手,建立过程中,服务端会收到两次消息,分别对应连接的半连接状态和全连接状态。服务器收到客户端的一次握手信息,放入半连接队列,收到两次握手信息放入全连接队列。accept函数是从全连接队列中取出已经建立的连接的。

6.send

函数返回已发送的字节数

send有发送缓冲区,当缓冲区满的时候会阻塞等待

send可能存在写入数据不完整的情况

7.recv

recv函数可能存在读取的报文不完整的情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值