⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockcomp.c

📁 socket compent我自己封装的socket组件
💻 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 + -