#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#include "stdlib.h"
int main()
{
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
printf("WSAStartup() 初始化失败!\n");
return -1;
}
//socket()函数创建与指定的服务提供者绑定套接字
//参数 af:指定协议的地址家族,通常使用AF_INET
//参数 type:指定的套接字类型,SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
//参数 protocal:套接字使用的协议
//socket() 函数执行成功,返回新Socket的句柄,调用失败返回INVALID_SOCKET
//调用socket() 函数创建Socket后,该Socket就存在一个命名空间中,但并没有为其指定一个名称
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
printf("socket() 出错!\n");
}
//
struct sockaddr_in addr; //指定绑定的地址
int addr_len = sizeof(struct sockaddr_in); //地址的长度
int port = 9901;
int errCode;
//u_long htonl(u_long hostlong)
//该函数将u_long类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
//u_short htons(u_short hostshort)
//该函数将u_short类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind() 函数可以将本地地址与一个Socket绑定在一起,执行成功返回0,调用失败返回SOCKET_ERROR
//调用bind() 函数可以为未命名的的Socket 指定一个名称
//名称由地址家族,主机地址,端口号3部分组成(当使用Internet地址家族)
//下面的例子使用bind() 函数绑定TCP Socket 到本地地址的9901端口
errCode = bind(s, (SOCKADDR*)&addr, addr_len);
if (errCode == SOCKET_ERROR)
{
printf("bind() 出错\n");
exit(1);
}
//listen()函数可以将套接字设置为监听接入的状态
//参数 s:指定一个已经绑定但是尚未连接的套接字
//参数 backlog:指定等待连接队列的最大长度
//listen()函数执行成功返回0,调用失败返回SOCKET_ERROR
errCode = listen(s, 3);
if (errCode == SOCKET_ERROR)
{
printf("listen() 出错!\n");
exit(1);
}
SOCKET sockAccept; //执行accept() 函数后新建的用于实际通信的套接字
struct sockaddr_in from; //用于接受接入地址
int len = sizeof(struct sockaddr_in);
//使用accept() 函数在处于监听状态的套接字上接受接入请求
//参数 s:通过调用listen() 函数设置为监听状态的套接字
//参数 addr:输出参数,用于接受接入地址信息,这是一个可选参数,如果不关注地址,可以使用NULL
//参数 addrlen:输出参数,指定接入地址的长度,这是一个可选参数
//accept() 函数调用成功,返回一个新建的Socket句柄,该Socket用于实现服务器和客户端之间的通信,
//如果函数调用失败,则返回INVALID_SOCKET
sockAccept = accept(s, (struct sockaddr *)&sockAccept, &len);
if (sockAccept == INVALID_SOCKET)
{
printf("accept() 出错!\n");
}
else
{
//char FAR * inet_ntoa(struct in_addr in)
//该函数将in_addr结构体中的IP地址转换为点分法IP地址字符串
//参数 in:是in_addr结构体类型,表示要进行转换的IP地址,返回结果是char *类型的IP地址
printf("%s\n", inet_ntoa(from.sin_addr)); //打印接入地址
}
if (WSACleanup() == SOCKET_ERROR)
{
printf("WSACleanup() 出错!\n\n");
}
system("pause");
return 0;
}
/*
#if !defined(MAKEWORD)
#define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8))
#endif
#define SOCK_STREAM 1 // stream socket
#define SOCK_DGRAM 2 // datagram socket
#define SOCK_RAW 3 // raw-protocol interface
#define SOCK_RDM 4 //reliably-delivered message
#define SOCK_SEQPACKET 5 //sequenced packet stream
#define AF_INET 2 // internetwork: UDP, TCP, etc.
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
// IPv4 Socket address, Internet style
//
typedef struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
short sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)
USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;
// Structure used to store most addresses.
//
typedef struct sockaddr {
#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family; // Address family.
#endif //(_WIN32_WINNT < 0x0600)
CHAR sa_data[14]; // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
#ifndef s_addr
#pragma once
//
// IPv4 Internet address
// This is an 'on-wire' format structure.
//
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr //can be used for most tcp & ip code
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
#endif
*/
#pragma comment(lib, "ws2_32.lib")
#include "stdlib.h"
int main()
{
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
printf("WSAStartup() 初始化失败!\n");
return -1;
}
//socket()函数创建与指定的服务提供者绑定套接字
//参数 af:指定协议的地址家族,通常使用AF_INET
//参数 type:指定的套接字类型,SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
//参数 protocal:套接字使用的协议
//socket() 函数执行成功,返回新Socket的句柄,调用失败返回INVALID_SOCKET
//调用socket() 函数创建Socket后,该Socket就存在一个命名空间中,但并没有为其指定一个名称
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
printf("socket() 出错!\n");
}
//
struct sockaddr_in addr; //指定绑定的地址
int addr_len = sizeof(struct sockaddr_in); //地址的长度
int port = 9901;
int errCode;
//u_long htonl(u_long hostlong)
//该函数将u_long类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
//u_short htons(u_short hostshort)
//该函数将u_short类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind() 函数可以将本地地址与一个Socket绑定在一起,执行成功返回0,调用失败返回SOCKET_ERROR
//调用bind() 函数可以为未命名的的Socket 指定一个名称
//名称由地址家族,主机地址,端口号3部分组成(当使用Internet地址家族)
//下面的例子使用bind() 函数绑定TCP Socket 到本地地址的9901端口
errCode = bind(s, (SOCKADDR*)&addr, addr_len);
if (errCode == SOCKET_ERROR)
{
printf("bind() 出错\n");
exit(1);
}
//listen()函数可以将套接字设置为监听接入的状态
//参数 s:指定一个已经绑定但是尚未连接的套接字
//参数 backlog:指定等待连接队列的最大长度
//listen()函数执行成功返回0,调用失败返回SOCKET_ERROR
errCode = listen(s, 3);
if (errCode == SOCKET_ERROR)
{
printf("listen() 出错!\n");
exit(1);
}
SOCKET sockAccept; //执行accept() 函数后新建的用于实际通信的套接字
struct sockaddr_in from; //用于接受接入地址
int len = sizeof(struct sockaddr_in);
//使用accept() 函数在处于监听状态的套接字上接受接入请求
//参数 s:通过调用listen() 函数设置为监听状态的套接字
//参数 addr:输出参数,用于接受接入地址信息,这是一个可选参数,如果不关注地址,可以使用NULL
//参数 addrlen:输出参数,指定接入地址的长度,这是一个可选参数
//accept() 函数调用成功,返回一个新建的Socket句柄,该Socket用于实现服务器和客户端之间的通信,
//如果函数调用失败,则返回INVALID_SOCKET
sockAccept = accept(s, (struct sockaddr *)&sockAccept, &len);
if (sockAccept == INVALID_SOCKET)
{
printf("accept() 出错!\n");
}
else
{
//char FAR * inet_ntoa(struct in_addr in)
//该函数将in_addr结构体中的IP地址转换为点分法IP地址字符串
//参数 in:是in_addr结构体类型,表示要进行转换的IP地址,返回结果是char *类型的IP地址
printf("%s\n", inet_ntoa(from.sin_addr)); //打印接入地址
}
if (WSACleanup() == SOCKET_ERROR)
{
printf("WSACleanup() 出错!\n\n");
}
system("pause");
return 0;
}
/*
#if !defined(MAKEWORD)
#define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8))
#endif
#define SOCK_STREAM 1 // stream socket
#define SOCK_DGRAM 2 // datagram socket
#define SOCK_RAW 3 // raw-protocol interface
#define SOCK_RDM 4 //reliably-delivered message
#define SOCK_SEQPACKET 5 //sequenced packet stream
#define AF_INET 2 // internetwork: UDP, TCP, etc.
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
// IPv4 Socket address, Internet style
//
typedef struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
short sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)
USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;
// Structure used to store most addresses.
//
typedef struct sockaddr {
#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family; // Address family.
#endif //(_WIN32_WINNT < 0x0600)
CHAR sa_data[14]; // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
#ifndef s_addr
#pragma once
//
// IPv4 Internet address
// This is an 'on-wire' format structure.
//
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr //can be used for most tcp & ip code
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
#endif
*/