📄 sockcomp.c
字号:
#include "sockcomp.h"
#include "mytype.h"
//initiate the socket version
MYBOOL initsockver(UCHAR majorversion, UCHAR minorversion)
{
#if defined (WIN32)
UINT wVersionRequested;
WSADATA wsaData;
int ret;
wVersionRequested = MYMAKEWORD(majorversion, minorversion);
ret = WSAStartup(wVersionRequested, &wsaData);
if (ret != 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("Can not find socket dll");
#endif
return WRONG;
}
if (LOBYTE(wsaData.wVersion) != minorversion || HIBYTE(wsaData.wVersion) != majorversion)
{
WSACleanup();
return WRONG;
}
#endif
return RIGHT;
}
//create a socket
int mysocket(int af, int type, int protocol)
{
int s;
if ((s = socket(af, type, protocol)) == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("Create Socket Failed\n");
#endif
return -1;
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Create Socket %d succeed!\n", s);
#endif
}
return s;
}
//绑定socket到某个端口
MYBOOL mybind(int s, struct sockaddr_in name, int namelen)
{
int ret;
if ((ret = bind(s, (struct sockaddr *)&name, namelen) != 0 ))
{
#if defined (SOCKCOMP_DEBUG)
printf("Bind socket %d to port %d of address %s failed!\n", s, ntohs(name.sin_port), inet_ntoa(name.sin_addr));
#endif
return WRONG;
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Bind socket %d to port %d of address %s successed!\n", s, ntohs(name.sin_port), inet_ntoa(name.sin_addr));
#endif
}
return RIGHT;
}
//地址复用
MYBOOL SetReuseAddr(int s, MYBOOL reuseaddr)
{
int ret;
ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr));
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
if (reuseaddr)
{
printf("Reuse socket %d failed!\n", s);
}
else
{
printf("Cancel Reuse socket %d failed!\n", s);
}
#endif
return WRONG;
}
else
{
#if defined (SOCKCOMP_DEBUG)
if (reuseaddr)
{
printf("Reuse socket %d successed!\n", s);
}
else
{
printf("Cancel Reuse socket %d successed!\n", s);
}
#endif
}
return RIGHT;
}
//连接到服务器
MYBOOL myconnect(int s, struct sockaddr_in name, int namelen)
{
int ret;
if ((ret = connect(s, (struct sockaddr *)&name, namelen)) == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("Block connect to server %s port %d failed!\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port));
#endif
#ifdef WIN32
ret = WSAGetLastError();
printsocketerror(ret);
#endif
return WRONG;
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("Block connect to server %s port %d successed!\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port));
#endif
}
return RIGHT;
}
//通过非阻塞模式连接
MYBOOL mynbconnect(int s, struct sockaddr_in name, int namelen, long second, long usecond)
{
MYBOOL ret;
int error, len;
struct timeval tmv;
fd_set wfds;
len = sizeof(int);
setsocketmode(s, 1);//enable no block mode
ret = WRONG;
if ((connect(s, (struct sockaddr *)&name, namelen)) == -1)
{
tmv.tv_sec = second;
tmv.tv_usec = usecond;
FD_ZERO(&wfds);
FD_SET(s, &wfds);
if ((select(s+1, NULL, &wfds, NULL, &tmv)) > 0)
{
if (FD_ISSET(s, &wfds))
{
getsockopt(s, SOL_SOCKET, SO_ERROR, (char *)&error, &len);
if(error == 0)
{
ret = RIGHT;
}
else
{
ret = WRONG;
}
}
else
{
ret = WRONG;
}
}
else
{
ret = WRONG;
}
}
else
{
ret = WRONG;
}
setsocketmode(s, 0);//disable no block mode
if (!ret)
{
#if defined (SOCKCOMP_DEBUG)
printf("No block connect to server %s port %d failed!\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port));
#endif
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("No block connect to server %s port %d successed!\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port));
#endif
}
return ret;
}
//查询套接口的状态
MYBOOL getsocketstatus(int s)
{
int ret;
int error=-1, len;
struct timeval tmv;
fd_set writefds;
len = sizeof(int);
tmv.tv_sec = 0;
tmv.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
ret = select(s+1, NULL, &writefds, NULL, &tmv);
if (ret > 0)
{
if (FD_ISSET(s, &writefds))
{
getsockopt(s, SOL_SOCKET, SO_ERROR, (char *)&error, &len);
if(error == 0)
{
return RIGHT;
}
else
{
return WRONG;
}
}
else
{
return WRONG;
}
}
return WRONG;
}
//得到本地主机的信息
void getlocalhostinfo(UCHAR * lhn, UCHAR * lha)
{ /*
struct hostent *localhostaddr;
UINT addrcount;
UINT i;
gethostname(lhn,256);
localhostaddr = gethostbyname(lhn);
printf("The local_host_name is %s\n", lhn);
if(localhostaddr != 0)
{
addrcount = (strlen(*localhostaddr->h_addr_list) - 14) / 4;
// addrcount = strlen(*localhostaddr->h_addr_list);
for (i=0; i<addrcount; i++)
{
wsprintf(lha, "%d.%d.%d.%d",
(localhostaddr->h_addr_list[i][0]&0x00ff),
(localhostaddr->h_addr_list[i][1]&0x00ff),
(localhostaddr->h_addr_list[i][2]&0x00ff),
(localhostaddr->h_addr_list[i][3]&0x00ff));
printf("The local_host_address%d is %s\n", i+1, lha);
}
} */
}
//得到远程主机的信息
void getremotehostinfo(int s, struct sockaddr_in remote_host_addr)
{
int namelen;
namelen = sizeof(struct sockaddr);
getpeername(s, (struct sockaddr *)&remote_host_addr, &namelen);
}
//设置套接口成非阻塞/阻塞模式
//set s to block mode when ul is zero and other set to no block mode
BOOL setsocketmode(int s, ULONG ul)
{
int ret;
#if defined (WIN32)
ret = ioctlsocket(s, FIONBIO, (ULONG *)&ul);
#elif defined (LINUX)
ret = ioctl(s, FIONBIO, (ULONG *)&ul);
#endif
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("set socket mode failed!\n");
#endif
return WRONG;
}
if (ret == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("set socket mode successed!\n");
#endif
}
return RIGHT;
}
//读取数据
int myrecv(int s, UCHAR * buf, int len, int flags)
{
int i;
int ret;
ret = recv(s, buf, len, flags);
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("receive data error!\n");
#endif
return -1;
}
if (ret == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("receive 0 data!\n");
#endif
return 0;
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("receive %d data succeed!\n", ret);
#endif
for (i=0; i<ret; i++)
{
#if defined (SOCKCOMP_DEBUG)
printf("recvbuff[%d]: %d\n", i, buf[i]);
#endif
}
}
return ret;
}
//使用SELECT模型读取数据
int myselectrecv(int s, UCHAR * buf, int len, int flags)
{
fd_set readfds;
int ret, i, length;
struct timeval tmv;
tmv.tv_sec = 2;
tmv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(s, &readfds);
if((ret = select(s+1, &readfds, NULL, NULL, &tmv) == -1))
{
#if defined (SOCKCOMP_DEBUG)
printf("select error!\n");
#endif
return -1;
}
if (ret > 0)
{
if (FD_ISSET(s, &readfds))
{
length = recv(s, buf, len, flags);
if (length == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("receive data failed!\n");
#endif
return -1;
}
if (length == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("receive 0 bytes data, this means the connection was closed by server!\n");
#endif
return 0;
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("receive data succeed!\n");
#endif
for (i=0; i<ret; i++)
{
#if defined (SOCKCOMP_DEBUG)
printf("recvbuff[%d]: %d\n", i, buf[i]);
#endif
}
return length;
}
}
}
return ret;
}
//设置接收超时时间
MYBOOL setrecvtimeout(int s, int timeout)
{
int ret;
TIMEVAL tm;
tm.tv_sec = 0;
tm.tv_usec = timeout;
ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tm, sizeof(tm));
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("Set Receive timeout of socket %d to value %d failed!\n", s, timeout);
#endif
return WRONG;
}
#if defined (SOCKCOMP_DEBUG)
printf("Set Receive timeout of socket %d to value %d successed!\n", s, timeout);
#endif
return RIGHT;
}
//设置发送超时时间
MYBOOL setsendtimeout(int s, int timeout)
{
int ret;
TIMEVAL tm;
tm.tv_sec = 0;
tm.tv_usec = timeout;
ret = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&tm, sizeof(tm));
if (ret == -1)
{
return WRONG;
}
return RIGHT;
}
//屏蔽Nagle算法
MYBOOL masknagle(int s, MYBOOL nodelay)
{
int ret;
ret = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay));
if (ret == -1)
{
return WRONG;
}
return RIGHT;
}
//发送数据
MYBOOL mysend(int s, const UCHAR * str)
{
int ret;
int left;
int index;
left = ((str[2] & 0x7F) << 8) + str[3];
index = 0;
while(left>0)
{
ret = send(s, &str[index], left, 0);
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("send data failed!\n");
#endif
return WRONG;
}
if (ret == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("send data failed!\n");
#endif
return WRONG;
}
else
{
left = left - ret;
index = index + ret;
}
}
#if defined (SOCKCOMP_DEBUG)
printf("send %d data succeed!\n", ret);
#endif
for (index=0; index<ret; index++)
{
#if defined (SOCKCOMP_DEBUG)
printf("send str[%d]: %d\n", index, str[index]);
#endif
}
#if defined (SOCKCOMP_DEBUG)
printf("\n");
#endif
return RIGHT;
}
//发送实时数据,使用SELECT模型
void myselectsend(int s, const UCHAR * str)
{
fd_set writefds;
int ret;
UINT left;
UINT index;
while(RIGHT)
{
FD_ZERO(&writefds);
FD_SET(s, &writefds);
if((ret = select(s+1, NULL, &writefds, NULL, NULL) == -1))
{
#if defined (SOCKCOMP_DEBUG)
printf("socket is busy!\n");
#endif
}
if (ret > 0)
{
if (FD_ISSET(s, &writefds))
{
left = strlen(str);
index = 0;
while(left>0)
{
ret = send(s, &str[index], left, 0);
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("send data failed!\n");
#endif
return;
}
if (ret == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("send data failed!\n");
#endif
return;
}
else
{
left = left - ret;
index = index + ret;
}
#if defined (SOCKCOMP_DEBUG)
printf("send data succeed!\n");
#endif
}
}
}
}
}
//关闭套接字
MYBOOL myclosesocket(int s)
{
int ret=0;
#if defined (WIN32)
ret = closesocket(s);
#elif defined (LINUX)
ret = close(s);
#endif
if (ret == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("close socket %d successed!\n", s);
#endif
}
else
{
#if defined (SOCKCOMP_DEBUG)
printf("close socket %d failed!\n", s);
#endif
return WRONG;
}
return RIGHT;
}
//卸载SOCKET DLL
MYBOOL myWSACleanup()
{
#if defined (WIN32)
int ret;
ret = WSACleanup();
if (ret == -1)
{
#if defined (SOCKCOMP_DEBUG)
printf("clean up socket failed!\n");
#endif
return WRONG;
}
if (ret == 0)
{
#if defined (SOCKCOMP_DEBUG)
printf("clean up socket successed!\n");
#endif
}
#endif
return RIGHT;
}
//输出socket错误
void printsocketerror(UINT errorcode)
{
/* switch(errorcode)
{
case WSANOTINITIALISED:
printf("在使用此API之前应首先成功地调用WSAStartup()。\n");
break;
case WSAENETDOWN:
printf("WINDOWS套接口实现检测到网络子系统失效。\n");
break;
case WSAEADDRINUSE:
printf("所指的地址已在使用中。\n");
break;
case WSAEINTR:
printf("通过一个WSACancelBlockingCall()来取消一个(阻塞的)调用。\n");
break;
case WSAEINPROGRESS:
printf("一个阻塞的WINDOWS套接口调用正在运行中。\n");
break;
case WSAEADDRNOTAVAIL:
printf("在本地机器上找不到所指的地址。\n");
break;
// case WSAENOTSUPPORT:
// printf("所指族中地址无法与本套接口一起使用。\n");
// break;
case WSAECONNREFUSED:
printf("连接尝试被强制拒绝。\n");
break;
// case WSAEDESTADDREQ:
// printf("需要目的地址。\n");
// break;
case WSAEFAULT:
printf("namelen参数不正确。\n");
break;
case WSAEINVAL:
printf("套接口没有准备好与一地址捆绑。\n");
break;
case WSAEISCONN:
printf("套接口早已连接。\n");
break;
case WSAEMFILE:
printf("无多余文件描述字。\n");
break;
case WSAENETUNREACH:
printf("当前无法从本主机访问网络。\n");
break;
case WSAENOBUFS:
printf("无可用缓冲区。套接口未被连接。\n");
break;
case WSAENOTSOCK:
printf("描述字不是一个套接口。\n");
break;
// case WSAETIMEOUT:
// printf("超时时间到。\n");
// break;
case WSAEWOULDBLOCK:
printf("套接口设置为非阻塞方式且连接不能立即建立。可用select()调用对套接口写,因为select()时会进行连接。\n");
break;
default:
break;
} */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -