2.1 socket使用基础

1.引用头文件

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

2.创建socket

int socket(int domain, int type, int protocol);

domain参数很多,但实际使用上,目前使用AF_INET(IPV4)

参数含义
AF_INETIPV4地址
AF_INET6IPV6地址
....

type参数

参数含义
SOCK_STREAMTCP连接
SOCK_DGRAMUDP连接
SOCK_RAW原始套接字
...

protocol参数,一般默认为0

举例:

/*创建TCP连接*/
int iSock = socket(AF_INET, SOCK_STREAM, 0);
/*创建UDP连接*/
int sockfd=socket(AF_INET,SOCK_DGRAM,0);

3.关闭sock

close(socket);

4.bind

    struct sockaddr_in server_addr;
 
    memset(&server_addr, 0, sizeof(server_addr) );
 
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(1234); /*绑定端口为1234*/
    inet_aton("192.168.1.100", &server_addr.sin_addr); /*绑定地址为192.168.1.100*/

    int ret = bind(iSock, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in));
    if(ret < 0)
    {
        return false;
    }
    
    return true; 

5.connect

    struct sockaddr_in server_addr;
    
    int iSock = socket(AF_INET, SOCK_STREAM, 0);
    if(iSock <= 0)
    {
        return false;
    }
    
    /*添加非阻塞配置*/
    SockNonBlockSet(iSock);
 
    memset(&server_addr, 0, sizeof(server_addr) ); 
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(iPort);
    inet_aton(szIPAddr, &server_addr.sin_addr);

    int ret = connect(iSock, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in));
    if(ret < 0)
    {
        /*因为sock设置了非阻塞,connect函数会立即返回,此时可能三步握手还没完成,所以需要判断sock是否可用*/
        if(errno != EINPROGRESS)
        {
            close(iSock);
            return false;
        }

        if(!SockFDCheck(iSock))
        {
            close(iSock);
            return false;
        }
    }

判断sock是否可用

bool SockFDCheck(int fd)
{
    fd_set fdr, fdw;
    struct timeval timeout;
    
    FD_ZERO(&fdr);
    FD_ZERO(&fdw);
    FD_SET(fd, &fdr);
    FD_SET(fd, &fdw);
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    
    int rc = select(fd + 1, &fdr, &fdw, NULL, &timeout);

    /*select调用失败*/
    if (rc < 0) 
    {
        return false;
    }

    /*连接超时*/
    if (rc == 0) 
    {
        return false;
    }
    /*[1] 当连接成功建立时,描述符变成可写,rc=1*/
    if (rc == 1 && FD_ISSET(fd, &fdw)) 
    {
        return true;
    }
    
    /*[2] 当连接建立遇到错误时,描述符变为即可读,也可写,rc=2 遇到这种情况,可调用getsockopt函数*/
    if (rc == 2) 
    {
        return false;
    }

    return false;
}

6.sock设置地址复用

    int optval = 1;
    if(setsockopt(iSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
    {
        return false;
    }

    return true;

7.sock设置非阻塞

    int flags;
    flags=fcntl(iSock,F_GETFL,0);
    fcntl(iSock,F_SETFL,flags|O_NONBLOCK);

8.sock设置不延迟

    int optval = 1;
    if(setsockopt(iSock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)) < 0)
    {
        return false;
    }

9.sock设置发送缓冲区

    int optval = 200 * 1024;
    if(setsockopt(iSock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) < 0)
    {
        return false;
    }

10.sock设置接收缓冲区

    int optval = 200 * 1024;
    if(setsockopt(iSock, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval)) < 0)
    {
        return false;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值