📄 sock_common.h
字号:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#define MAX_LINE_SIZE 1024
#define INIT_READBUFFER(B) B.read_count = 0
typedef struct ReadBuffer_t
{
int read_count;
char *read_ptr;
char read_buf[MAX_LINE_SIZE];
} ReadBuffer;
/***************************************************************************************************************
sockerror 用来输出网络函数的错误信息
***************************************************************************************************************/
void sockerror(const char *format, ...)
{
int errno;
va_list args;
va_start(args, format);
fprintf(stderr, format, args);
va_end(args);
errno = WSAGetLastError();
switch (errno)
{
case WSAEADDRINUSE:
fprintf(stderr,"WSAEADDRINUSE:The specified address is already in use.");
break;
case WSAEADDRNOTAVAIL:
fprintf(stderr,"WSAEADDRNOTAVAIL:The specified address is not available from the local machine.");
break;
case WSAEAFNOSUPPORT:
fprintf(stderr,"WSAEAFNOSUPPORT:Addresses in the specified family cannot be used with this socket.");
break;
case WSAECONNREFUSED:
fprintf(stderr,"WSAECONNREFUSED:The attempt to connect was forcefully rejected.");
break;
case WSAEDESTADDRREQ:
fprintf(stderr,"WSAEDESTADDRREQ:A destination address is required.");
break;
case WSAEFAULT:
fprintf(stderr,"WSAEFAULT:The lpSockAddrLen argument is incorrect.");
break;
case WSAEINVAL:
fprintf(stderr,"WSAEINVAL:The socket is already bound to an address.");
break;
case WSAEISCONN:
fprintf(stderr,"WSAEISCONN:The socket is already connected.");
break;
case WSAEMFILE:
fprintf(stderr,"WSAEMFILE:No more file descriptors are available.");
break;
case WSAENETUNREACH:
fprintf(stderr,"WSAENETUNREACH:The network cannot be reached from this host at this time.");
break;
case WSAENOBUFS:
fprintf(stderr,"WSAENOBUFS:No buffer space is available. The socket cannot be connected.");
break;
case WSAENOTCONN:
fprintf(stderr,"WSAENOTCONN:The socket is not connected.");
break;
case WSAENOTSOCK:
fprintf(stderr,"WSAENOTSOCK:The descriptor is a file, not a socket.");
break;
case WSAETIMEDOUT:
fprintf(stderr,"WSAETIMEDOUT:The attempt to connect timed out without establishing a connection. ");
break;
default:
fprintf(stderr,"WSAEError: Unknown! ");
break;
}
fprintf(stderr,"\n");
}
/***************************************************************************************************************
readline 用来从网络中读取一行,采用一次读一个字符的方式
***************************************************************************************************************/
int ReadLine1(SOCKET s,char FAR *buf,int max_len)
{
char c,*ptr;
int n,rc;
ptr = buf;
for(n = 1;n < max_len;n++)
{
rc = recv(s,&c,1,0);
if(rc == 1)
{
*ptr++ = c;
if(c == '\n')
break;
}
else // EOF or SOCKET_ERROR
{
if(n==1) // no data read
return rc;
else
break;
}
}
*ptr = 0;
return n;
}
/***************************************************************************************************************
ReadLine 用来从网络中读取一行,先将数据读取到Buffer中,再从Buffer中读取一行
***************************************************************************************************************/
static int my_read(SOCKET s,char *ptr,ReadBuffer *pRB)
{
if( pRB->read_count <= 0)
{
pRB->read_count = recv(s,pRB->read_buf,MAX_LINE_SIZE,0);
if(pRB->read_count <= 0) // EOF or SOCKET_ERROR
return pRB->read_count;
pRB->read_ptr = pRB->read_buf;
}
pRB->read_count--;
*ptr = *pRB->read_ptr++;
return 1;
}
int ReadLine(SOCKET s,char FAR *buf,int max_len,ReadBuffer *pRB)
{
char c,*ptr;
int n,rc;
ptr = buf;
for(n = 1;n < max_len;n++)
{
rc = my_read(s,&c,pRB);
if(rc == 1)
{
*ptr++ = c;
if(c == '\n')
break;
}
else // EOF or SOCKET_ERROR
{
if(n==1) // no data read
return 0;
else
break;
}
}
*ptr = 0;
return n;
}
int Read(SOCKET s,char FAR *buf,int n,ReadBuffer *pRB)
{
int rc;
if(pRB->read_count > 0)
{
rc = (pRB->read_count < n) ? pRB->read_count:n;
memcpy(buf,pRB->read_ptr,rc);
pRB->read_count -= rc;
pRB->read_ptr += rc;
return rc;
}
rc = recv(s,buf,n,0);
return rc;
}
/***************************************************************************************************************
ReadN 用来从网络中读取n个字节
***************************************************************************************************************/
int ReadN(SOCKET s,char FAR *buf,int n,ReadBuffer *pRB)
{
int count = 0;
int rc;
if(pRB->read_count > 0)
{
rc = (pRB->read_count < n) ? pRB->read_count:n;
memcpy(buf,pRB->read_ptr,rc);
pRB->read_count -= rc;
pRB->read_ptr += rc;
count = rc;
}
while(count < n)
{
rc = recv(s,buf + count,n - count,0);
if(rc <= 0)
break;
count += rc;
}
return count;
}
/***************************************************************************************************************
WriteN 用来从网络中写取n个字节
***************************************************************************************************************/
int WriteN(SOCKET s,char FAR *buf,int n)
{
int count = 0;
int sc;
while(count < n)
{
sc = send(s,buf + count,n - count,0);
if(sc < 0)
return sc;
if(sc == 0)
Sleep(100);
count += sc;
}
return count;
}
/***************************************************************************************************************
Constructsockaddr 用来从根据地址strAddr和端口strPort自动构造好一个地址机构
他会自动判断strAddr是域名还是IP地址,然后进行相应转换
***************************************************************************************************************/
int ConstructSockaddr(SOCKADDR_IN* paddr_in,char * strAddr,char * strPort)
{
unsigned short port;
struct hostent* phostent;
port = atoi(strPort);
if (port == 0)
return 0;
paddr_in->sin_family = AF_INET;
paddr_in->sin_port = htons(port);
paddr_in->sin_addr.s_addr = inet_addr(strAddr);
if(paddr_in->sin_addr.s_addr != INADDR_NONE)
return 1;
phostent = gethostbyname(strAddr);
if (phostent == NULL)
{
sockerror("Resove name %s error!",strAddr);
return 0;
}
paddr_in->sin_addr = *((IN_ADDR*) phostent->h_addr);
if(paddr_in->sin_addr.s_addr != INADDR_NONE)
return 1;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -