/************************************************************************ * AUTHOR: NiuJiuRu * FILENAME: swtcp.c * DESCRIPTION: TCP socket * NOTE: * HISTORY: * 1, [2010-11-30] created by NiuJiuRu ***********************************************************************/ #include "swapi.h" #include "swtcp.h" /* 创建一个tcp socket */ int sw_tcp_socket() { return socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); } /* 关闭一个tcp socket */ void sw_tcp_close(int skt) { closesocket(skt); } /* 连接远端 */ int sw_tcp_connect(int skt, unsigned int ip, unsigned short port) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = ip; addr.sin_port = port; return connect(skt, (struct sockaddr *)&addr, sizeof(addr)); } /* 绑定接收地址和端口, sever使用bind()与本机绑定, client使用connect()与远程主机连接 */ int sw_tcp_bind(int skt, unsigned int ip, unsigned short port) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = ip; addr.sin_port = port; return bind(skt, (struct sockaddr *)&addr, sizeof(addr)); } /* 开始监听, max为处理连接的队列长度, 建议设置为: SOMAXCONN */ int sw_tcp_listen(int skt, int max) { return listen(skt, max); } /* 等待远程连接(从连接队列中读取第一个已完成的连接, 队列长度减一) */ int sw_tcp_accept(int skt, unsigned int *ip, unsigned short *port) { struct sockaddr_in from; unsigned int slen = sizeof(from); skt = accept(skt, (struct sockaddr *)&from, &slen); if(0 <= skt) { if(ip) *ip = from.sin_addr.s_addr; if(port) *port = from.sin_port; } return skt; } /* 发送数据 */ int sw_tcp_send(int skt, const char *buf, int send_len) { return send(skt, buf, send_len, 0); } /* 接收数据 */ int sw_tcp_recv(int skt, char *buf, int buf_size) { return recv(skt, buf, buf_size, 0); } /* 配置tcp socket */ int sw_tcp_ioctl(int skt, int type, unsigned long *val) { return ioctlsocket(skt, (long)type, val); } /* 检测tcp socket的状态, timeout单位为ms */ int sw_tcp_select(int skt, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout) { struct timeval tv = { 0 }; if(readfds) { FD_ZERO(readfds); FD_SET((unsigned int)skt, readfds); } if(writefds) { FD_ZERO(writefds); FD_SET((unsigned int)skt, writefds); } if(exceptfds) { FD_ZERO(exceptfds); FD_SET((unsigned int)skt, exceptfds); } if(0 <= timeout) { tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000; return select(skt+1, readfds, writefds, exceptfds, &tv); } else return select(skt+1, readfds, writefds, exceptfds, NULL); }