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_INET | IPV4地址 |
AF_INET6 | IPV6地址 |
.... |
type参数
参数 | 含义 |
SOCK_STREAM | TCP连接 |
SOCK_DGRAM | UDP连接 |
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;
}