- 浏览: 38145 次
- 性别:
- 来自: 安徽
最新评论
原始套接字是WINSOCK公开的一个套接字编程接口,它让我们可以在 IP 层对套接字进行编程,控制其行为,常见的应用有抓包 (Sniffer)、分析包、洪水攻击、ICMP ping等,但它不能截取包(所谓的截取包就是把包拦截下来,要做到这种“防火墙”的功能,还需要再低一层的驱动层才可以做到)。但是能把网络上的包复制到本机就已经是一个很有用的功能了。我就曾经试过在一个局域网里打开我的SNIFFER,然后把同事们电脑发出的包都复制过来了。然后如果再对包进行一些分析,哼哼。。。
其实原始套接字最根本的就是可以在IP层构造自己的IP包,然后把这个IP包发送出去。同样,我们可以把从TCP/UDP传输层过来的包抓取过来并进行分析。。。
要写原始套接字的程序其实也很容易,因为WINDOWS已经帮我们定义实现好了这些接口(WINSOCK)。另外我们还要有一些定义,就是IP包头、UDP包头等的那些结构定义,具体请查看下面的代码。
下面是我定义的一个RawSniffer类,这个类是使用了原始套接字来实现一个侦听器,这个类还依赖于MFC(我一直都在WINDOWS平台下开发,用的比较多的也是MFC,所以对MFC有点偏好。。。)。下面是类的代码:
// 头文件
#ifndef RAW_DEF_H
#define RAW_DEF_H
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include <ws2tcpip.h>
#include <mstcpip.h> // 此文件是 Windows platform SDK 的函数,如果找不到,请安装SDK
#define PROTOCOL_STRING_ICMP_TXT "ICMP"
#define PROTOCOL_STRING_TCP_TXT "TCP"
#define PROTOCOL_STRING_UDP_TXT "UDP"
#define PROTOCOL_STRING_SPX_TXT "SPX"
#define PROTOCOL_STRING_NCP_TXT "NCP"
#define PROTOCOL_STRING_UNKNOW_TXT "UNKNOW"
// 定义IP首部
typedef struct ip_hdr
{
unsigned char h_verlen; // 4位首部长度,4位IP版本号
unsigned char tos; // 8位服务类型TOS
unsigned short total_len; // 16位总长度(字节)
unsigned short ident; // 16位标识
unsigned short frag_and_flags; // 3位标志位
unsigned char ttl; // 8位生存时间 TTL
unsigned char proto; // 8位协议 (TCP, UDP 或其他)
unsigned short checksum; // 16位IP首部校验和
unsigned int sourceIP; // 32位源IP地址
unsigned int destIP; // 32位目的IP地址
}IPHEADER;
// 定义TCP伪首部
typedef struct tsd_hdr
{
unsigned long saddr; // 源地址
unsigned long daddr; // 目的地址
char mbz; // 0
char ptcl; // 协议类型 UDP的协议类型为17,TCP为6
unsigned short tcpl; // TCP数据包长度
}PSDHEADER;
// 定义TCP首部
typedef struct tcp_hdr
{
USHORT th_sport; // 16位源端口
USHORT th_dport; // 16位目的端口
unsigned int th_seq; // 32位序列号
unsigned int th_ack; // 32位确认号
unsigned char th_lenres; // 4位首部长度/6位保留字
unsigned char th_flag; // 6位标志位
USHORT th_win; // 16位窗口大小
USHORT th_sum; // 16位校验和
USHORT th_urp; // 16位紧急数据偏移量
}TCPHEADER;
// 定义ICMP首部
typedef struct icmp_hdr
{
unsigned char i_type; // 类型
unsigned char i_code; // 代码
unsigned short i_cksum; // 校验码
unsigned short i_id; // 非标准的ICMP首部
unsigned short i_seq;
unsigned long timestamp;
}ICMPHEADER;
// 定义UDP首部
// The UDP packet is lick this. Took from RFC768.
// 0 7 8 15 16 23 24 31
// +--------+--------+--------+--------+
// | Source | Destination |
// | Port | Port |
// +--------+--------+--------+--------+
// | | |
// | Length | Checksum |
// +--------+--------+--------+--------+
// |
// | data octets ...
// +---------------- ...
typedef struct udp_hdr // 8 Bytes
{
unsigned short uh_sport;
unsigned short uh_dport;
unsigned short uh_len;
unsigned short uh_sum;
} UDPHEADER;
/*
// 函数实现不要放在头文件,否则会导致在不同的地方重复定义
//CheckSum:计算校验和的子函数
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
*/
USHORT checksum(USHORT *buffer, int size);
// 回调函数
// 抓到一个包就会调用这个回调函数
typedef int (CALLBACK *CaptureDef)(CString &strMsg);
class YRawSniffer
{
public:
YRawSniffer();
~YRawSniffer();
BOOL StartAll();
BOOL ExitAll();
BOOL Capture(CaptureDef CaptureFunc = NULL);
BOOL StopCapture();
static DWORD WINAPI CaptureThread(LPVOID lpParam);
HANDLE m_hCaptureThread;
// Filter 过滤条件
BOOL m_bCapTCP;
BOOL m_bCapUDP;
BOOL m_bCapICMP;
CString m_strSrcIP;
CString m_strDstIP;
SOCKET m_rawSock;
// CString m_strFilePath;
private:
CaptureDef m_CaptureFunc;
BOOL m_bExitCapture;
IPHEADER m_ipHeader;
TCPHEADER m_tcpHeader;
ICMPHEADER m_icmpheader;
UDPHEADER m_udpheader;
};
#endif
// CPP 文件
#include "stdafx.h"
#include "RawDef.h"
//CheckSum:计算校验和的子函数
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
char * GetProtocol(int proto)
{
switch(proto)
{
case IPPROTO_ICMP: return PROTOCOL_STRING_ICMP_TXT;
case IPPROTO_TCP: return PROTOCOL_STRING_TCP_TXT;
case IPPROTO_UDP: return PROTOCOL_STRING_UDP_TXT;
default: return PROTOCOL_STRING_UNKNOW_TXT;
}
}
DWORD WaitForObjectEx( HANDLE hHandle, DWORD dwMilliseconds )
{
BOOL bRet;
MSG msg;
INT iWaitRet;
DWORD nTimeOut = 0;
while( (bRet = ::GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if( nTimeOut++ * 100 >= dwMilliseconds )
break;
iWaitRet = WaitForSingleObject(hHandle, 100);
if(iWaitRet != WAIT_TIMEOUT)
{
break;
}
if (bRet == -1)
{
break;
}
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
return iWaitRet;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
YRawSniffer *g_rawSniffer;
YRawSniffer::YRawSniffer()
{
m_bCapTCP = FALSE;
m_bCapUDP = FALSE;
m_bCapICMP = FALSE;
m_strSrcIP = "";
m_strDstIP = "";
m_rawSock = INVALID_SOCKET;
// m_strFilePath = "";
m_bExitCapture = FALSE;
m_CaptureFunc = NULL;
m_hCaptureThread = NULL;
g_rawSniffer = this;
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0)
{
TRACE1("WSAStartup() ERROR! %d", GetLastError());
return;
}
}
YRawSniffer::~YRawSniffer()
{
WSACleanup();
}
BOOL YRawSniffer::ExitAll()
{
m_bExitCapture = TRUE;
shutdown(m_rawSock, SD_BOTH);
if(m_hCaptureThread != NULL)
{
DWORD dwRet = 0;
dwRet = WaitForObjectEx(m_hCaptureThread, INFINITE);
if(dwRet == WAIT_OBJECT_0)
{
TRACE("CaptureThread exit Success!");
}
closesocket(m_rawSock);
m_rawSock = INVALID_SOCKET;
CloseHandle(m_hCaptureThread);
m_hCaptureThread = NULL;
}
TRACE("ExitAll OK!");
return TRUE;
}
BOOL YRawSniffer::StartAll()
{
m_bExitCapture = FALSE;
SOCKADDR_IN addr_in;
if(m_rawSock == INVALID_SOCKET)
m_rawSock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
BOOL flag = TRUE;
if(setsockopt(m_rawSock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) != 0)
{
TRACE1("setsockopt() ERROR! %d", WSAGetLastError());
return FALSE;
}
char LocalName[16];
struct hostent *pHost;
// 获取本机名
if (gethostname((char*)LocalName, sizeof(LocalName)-1) == SOCKET_ERROR)
{
TRACE1("gethostname error! %d", WSAGetLastError());
return FALSE;
}
// 获取本地 IP 地址
if ((pHost = gethostbyname((char*)LocalName)) == NULL)
{
TRACE1("gethostbyname error! %d", WSAGetLastError());
return FALSE;
}
// m_strSrcIP = pHost->h_addr_list[0];
addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0]; // IP
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);
if( bind(m_rawSock, (struct sockaddr *)&addr_in, sizeof(addr_in)) != 0)
{
TRACE1("bind error! %d", WSAGetLastError());
return FALSE;
}
// 设置网卡的I/O行为,接收网络上所有的数据包
DWORD dwValue = 1;
if( ioctlsocket(m_rawSock, SIO_RCVALL, &dwValue) != 0)
{
TRACE1("ioctlsocket error! %d", WSAGetLastError());
return FALSE;
}
return TRUE;
}
DWORD WINAPI YRawSniffer::CaptureThread(LPVOID lpParam)
{
//CFile fLog;
//BOOL bLogFile = FALSE;
// 打开记录文件
//if(g_rawSniffer->m_strFilePath == "")
// g_rawSniffer->m_strFilePath = "c://Capture.txt";
//if(g_rawSniffer->m_strFilePath != "")
// {
// if( !fLog.Open(g_rawSniffer->m_strFilePath, CFile::modeCreate|CFile::modeReadWrite) )
// TRACE1("file fLog Open failed! %d", GetLastError());
// else
// bLogFile = TRUE;
// }
const int MAX_RECEIVEBUF = 1000;
char recvBuf[MAX_RECEIVEBUF] = {0};
char msg[MAX_RECEIVEBUF] = {0};
char *ptr = NULL;
CString strLog, strTmp, strContent;
DWORD nTCPCnt = 0, nUDPCnt = 0, nICMPCnt = 0;
while(!g_rawSniffer->m_bExitCapture)
{
int ret = recv(g_rawSniffer->m_rawSock, recvBuf, MAX_RECEIVEBUF, 0);
if(ret == SOCKET_ERROR)
TRACE1("%d, recv(g_rawSniffer->m_rawSock, recvBuf, MAX_RECEIVEBUF, 0) failed!", GetLastError());
strLog = "";
strContent = "";
if(ret > 0)
{
g_rawSniffer->m_ipHeader = *(IPHEADER*)recvBuf;
// 取得正确的IP头长度
int iIphLen = sizeof(unsigned long) * (g_rawSniffer->m_ipHeader.h_verlen & 0xf);
int cpysize = 0;
// 过滤目标IP或者源IP
//if(g_rawSniffer->m_strSrcIP.Find(".") > 0
// || g_rawSniffer->m_strDstIP.Find(".") > 0)
{
if(g_rawSniffer->m_strSrcIP != ""
|| g_rawSniffer->m_strDstIP != "")
{
if( inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.sourceIP) != g_rawSniffer->m_strSrcIP
&& inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.destIP) != g_rawSniffer->m_strDstIP)
continue;
}
}
/*
// 过滤目标IP或者源IP
if(g_rawSniffer->m_strSrcIP != "")
{
if( inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.sourceIP) != g_rawSniffer->m_strSrcIP)
continue;
}
if(g_rawSniffer->m_strDstIP != "")
{
if( inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.destIP) != g_rawSniffer->m_strDstIP)
continue;
}
*/
if(g_rawSniffer->m_ipHeader.proto == IPPROTO_TCP && g_rawSniffer->m_bCapTCP)
{
nTCPCnt++;
g_rawSniffer->m_tcpHeader = *(TCPHEADER*)(recvBuf + iIphLen);
strTmp.Format("取得 %d TCP包", nTCPCnt); strLog += strTmp;
strTmp.Format("协议: %s /r/n", GetProtocol(g_rawSniffer->m_ipHeader.proto)); strLog += strTmp;
strTmp.Format("IP源地址: %s /r/n", inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.sourceIP)); strLog += strTmp;
strTmp.Format("IP目标地址: %s /r/n", inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.destIP)); strLog += strTmp;
strTmp.Format("TCP源端口号: %d /r/n", g_rawSniffer->m_tcpHeader.th_sport); strLog += strTmp;
strTmp.Format("TCP目标端口号:%d /r/n", g_rawSniffer->m_tcpHeader.th_dport); strLog += strTmp;
strTmp.Format("数据包长度: %d /r/n", ntohs(g_rawSniffer->m_ipHeader.total_len)); strLog += strTmp;
strTmp.Format("TCP数据包的报文内容:/r/n"); strLog += strTmp;
ptr = recvBuf + iIphLen + (4 * ((g_rawSniffer->m_tcpHeader.th_lenres & 0xf0)>>4|0));
cpysize = ntohs(g_rawSniffer->m_ipHeader.total_len) - (iIphLen + (4 * ((g_rawSniffer->m_tcpHeader.th_lenres & 0xf0)>>4|0)));
// ASCII码
memcpy(msg, ptr, cpysize);
for(int i = 0; i < cpysize ; i++)
{
if(msg[i] >= 32 && msg[i] < 255)
{
strContent.Format("%c", (unsigned char)msg[i]); strLog += strContent;
}
else
{
strContent.Format("."); strLog += strContent;
}
}
strTmp.Format("/r/n /r/n"); strLog += strTmp;
}
if(g_rawSniffer->m_ipHeader.proto == IPPROTO_ICMP && g_rawSniffer->m_bCapICMP)
{
nICMPCnt++;
g_rawSniffer->m_icmpheader = *(ICMPHEADER*)(recvBuf + iIphLen);
strTmp.Format("取得 %d ICMP包", nICMPCnt); strLog += strTmp;
strTmp.Format("协议: %s/r/n", GetProtocol(g_rawSniffer->m_ipHeader.proto)); strLog += strTmp;
strTmp.Format("IP源地址: %s/r/n", inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.sourceIP)); strLog += strTmp;
strTmp.Format("IP目标地址: %s/r/n", inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.destIP)); strLog += strTmp;
strTmp.Format("ICMP返回类型:%d/r/n", g_rawSniffer->m_icmpheader.i_type); strLog += strTmp;
strTmp.Format("ICMP返回代码:%d/r/n", g_rawSniffer->m_icmpheader.i_code); strLog += strTmp;
strTmp.Format("数据包长度: %d/r/n/r/n/r/n", ntohs(g_rawSniffer->m_ipHeader.total_len)); strLog += strTmp;
}
if(g_rawSniffer->m_ipHeader.proto == IPPROTO_UDP && g_rawSniffer->m_bCapUDP)
{
nUDPCnt++;
g_rawSniffer->m_udpheader = *(UDPHEADER*)(recvBuf + iIphLen);
strTmp.Format("取得 %d UDP包", nUDPCnt); strLog += strTmp;
strTmp.Format("协议: %s/r/n", GetProtocol(g_rawSniffer->m_ipHeader.proto)); strLog += strTmp;
strTmp.Format("IP源地址: %s/r/n", inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.sourceIP)); strLog += strTmp;
strTmp.Format("IP目标地址: %s/r/n", inet_ntoa(*(in_addr*)&g_rawSniffer->m_ipHeader.destIP)); strLog += strTmp;
strTmp.Format("UDP源端口号: %d/r/n", g_rawSniffer->m_udpheader.uh_sport); strLog += strTmp;
strTmp.Format("UDP目标端口号:%d/r/n", g_rawSniffer->m_udpheader.uh_dport); strLog += strTmp;
strTmp.Format("数据包长度: %d/r/n", ntohs(g_rawSniffer->m_ipHeader.total_len)); strLog += strTmp;
strTmp.Format("UDP数据包的报文内容:/r/n"); strLog += strTmp;
ptr = recvBuf + iIphLen + 8;
cpysize = ntohs(g_rawSniffer->m_ipHeader.total_len) - (iIphLen + 8);
memcpy(msg, ptr, cpysize);
strTmp.Format("ASCII码格式: /r/n");
for(int i = 0; i < cpysize; i++)
{
if(msg[i] >= 32 && msg[i] < 255)
{
strContent.Format("%c",(unsigned char)msg[i]); strLog += strContent;
}
else
{
strContent.Format("."); strLog += strContent;
}
}
strTmp.Format("/r/n/r/n"); strLog += strTmp;
strTmp.Format("16进制码格式: /r/n"); strLog += strTmp;
for(i = 0; i < cpysize; i++)
{
strTmp.Format("%2.2X ", (unsigned char)msg[i]); strLog += strTmp;
}
strTmp.Format("/r/n/r/n"); strLog += strTmp;
}
if(g_rawSniffer->m_CaptureFunc != NULL && strLog.GetLength() > 0 && strContent.GetLength() > 0)
g_rawSniffer->m_CaptureFunc(strLog);
Sleep(10);
}
}
// 关闭记录文件
// if(bLogFile)
// fLog.Close();
return 0;
}
BOOL YRawSniffer::Capture(CaptureDef CaptureFunc /*= NULL*/)
{
StartAll();
if(CaptureFunc != NULL)
m_CaptureFunc = CaptureFunc;
// 创建线程截取包
m_bExitCapture = FALSE;
m_hCaptureThread = CreateThread(NULL, 0, CaptureThread, NULL, 0, NULL);
if(NULL == m_hCaptureThread)
TRACE1(" /"m_hCaptureThread = CreateThread(NULL, 0, CaptureThread, NULL, 0, NULL)/" failed! %d ", GetLastError());
return TRUE;
}
BOOL YRawSniffer::StopCapture()
{
return ExitAll();
}
这个类的使用很简单,声明一个全局的对象(或者成员变量),使用它的Capture和StopCapture就可以了。记得在程序退出的时候也调用一下StopCapture。
调用Capture 函数的时候,需要把一些过滤条件赋给它:
// 过滤条件
g_sniffer.m_bCapTCP = m_bCapTCP; // 抓TCP包,TRUE为抓,FALSE不抓
g_sniffer.m_bCapUDP = m_bCapUDP; // 抓UDP包,TRUE为抓,FALSE不抓
g_sniffer.m_bCapICMP = m_bCapICMP; // 抓ICMP包,TRUE为抓,FALSE不抓
g_sniffer.m_strSrcIP = m_strSrcIP; // 包的源IP串,空为不限制
g_sniffer.m_strDstIP = m_strDstIP; // 包的目标IP串,空为不限制
g_sniffer.Capture(CapFunc);
抓到的包会在一个回调函数中把抓到的包格式化好了传给你。
例如我的回调函数是这样的:
int CALLBACK CapFunc(CString &strLog)
{
g_rawDlg->AddLog(strLog); // 把抓到的包在DLG的一个编辑框里输出
g_log.WriteLogFileRaw(strLog); // 写进一个LOG文件里
return 0;
}
有了上面的这些知识就可以使用这个类实现一个SNIFFER了,很简单的3步:1、把类加进工程 2、包含头文件,声明对象 3、使用这个对象的Capture和StopCapture。
上面还可以看出我原来的设计是把记录包的功能放在了类里。但是后面觉得这个类还是不要干那么多的活,让记录包的工作都放在上层吧。所以就用了回调函数。
通过上面代码的研究,你应该很明白原始套接字了吧,这项技术不但可以做SNIFFER,还可以实现洪水攻击等等(因为可以自己构造IP包)。
最后给出我使用这个类实现的一个程序界面,当然界面那块的逻辑需要你自己去处理了,需要的朋友请留下地址,我把例程发给你。
That's all, Happy every day!
发表评论
-
PPPD拨号返回结果码
2015-09-18 11:12 73200: pppd已经断开,或者已经成功建立连接后请求方又中 断 ... -
3G相关定时器说明
2014-08-06 10:05 883计时器和计数器RNC 计 ... -
PDP激活被拒绝原因码表
2012-07-19 20:55 2831om: http://wireless.agilent.com ... -
PDP激活被拒绝原因码表
2012-07-19 20:15 0方便查询:这些值是真正的原因,但要注意分析问题时尤其对二次开发 ... -
TCP重传
2012-07-03 20:23 1153为什么TCP存在重传 TCP是 ... -
MTK NVRAM
2012-06-28 19:50 1658nvram是程序用来搭建FAT文件系统的那一块,是fla ... -
TBF与PDP激活
2012-06-18 21:28 1196PDP先激活,CCCH上下行TBF建立流程如下:1、下行TBF ... -
C语言中的内存对齐问题
2012-05-29 10:31 788.C语言中的内存对齐 ... -
MTK内存管理
2012-04-20 00:36 4589MTK 内存管理 分类: MTK2011- ... -
MTK Timer
2012-04-18 14:33 41331. GPTI_StartItem 要精准很多,但是只能 ... -
TCP三次握手各种异常
2012-03-20 11:04 1405和TCP三次握手有关的面试题 分类: 网络 ... -
Windows API串口编程参考
2012-03-15 14:12 3448Windows API串口编程参 ... -
V.24 & V.35
2012-03-12 20:25 982V.24 & V.35 (2011-08 ... -
【C语言】while与for执行效率对比【转】
2012-03-12 19:00 1664【C语言】while与for执行效率对比【转】 C语言 ... -
[转]ASCII,Unicode,UTF-8,GB2312编码之间的关系
2012-03-12 18:59 942[转]ASCII,Unicode,UTF-8,GB231 ... -
NVRAM的简单添加 【转】
2012-02-29 10:14 851NVRAM的简单添加 MTK 在这里我只 ... -
MTK获取基站的cell_id 【转】
2012-02-29 10:07 1059MTK获取基站的cell_id 博客分类 ... -
MTK的HTTP连接方式
2012-02-29 10:08 892MTK的HTTP连接方式 博客分类: ... -
MTK中怎样创建和使用lib
2012-02-28 17:17 733MTK中怎样创建和使用lib 博客分类: MT ... -
MMI 和L4通信【转】
2012-02-28 17:16 1142MMI 和L4通信 博客分类: MTK ...
相关推荐
WinSocket API —— TCPIP连接 WinSocket API —— TCPIP连接 - cvbnm - 博客园
Winsocket API遵循BSD Unix的套接字模型,提供了一套跨平台的网络编程接口。 在VC++6.0环境下,使用Winsocket编程需要以下步骤: 1. **初始化**: 使用`WSAStartup()`函数启动Winsock服务,设置合适的版本号。这会...
在WinSocket中,可以通过`socket()`函数创建一个套接字,指定其协议类型(如TCP或UDP)、地址族(如IPv4或IPv6)以及套接字类型(如流式套接字或数据报套接字)。 2. **地址和端口**:每个套接字都关联有一个IP地址...
它通过在调用`select()`时提供一组套接字,让应用程序能够检测这些套接字是否准备好了读或写操作,而无需逐一调用阻塞函数。选择模型适用于低至中等负载的网络应用,特别是在套接字数量有限的情况下。 2. **异步...
2. **创建套接字**:使用`socket`函数创建一个套接字,指定其类型(TCP或UDP)、协议(如TCP/IP)以及地址族(如AF_INET代表IPv4)。 3. **服务器端绑定和监听**:Server端使用`bind`函数将套接字与特定的IP地址和...
Berkeley套接字是Unix系统中广泛使用的网络编程接口,而Winsock则使其功能得以在Windows上实现。这个实例旨在帮助开发者理解和掌握如何在Windows环境下创建基于套接字的网络应用程序。 VC++ 6.0是微软公司早期的一...
2. 创建套接字:使用`socket`函数创建一个套接字,指定协议类型(如TCP或UDP)、地址族(通常为AF_INET)和套接字类型(如SOCK_STREAM或SOCK_DGRAM)。 3. 绑定:使用`bind`函数将套接字与本地IP地址和端口号绑定,...
在WinSocket编程中,我们通常使用套接字(Socket)对象来实现TCP通信。 创建TCP服务器的步骤如下: 1. **初始化**: 使用`WSAStartup`函数启动Winsock库,设置版本号和配置信息。 2. **创建套接字**: 使用`socket`...
在Winsock编程中,我们需要理解如何创建和管理套接字(Socket),这是网络通信的基本单元。服务器端需要创建监听套接字,等待客户端的连接请求;客户端则需要创建连接套接字,主动发起连接。一旦连接建立,双方可以...
以上8个源代码示例涵盖了Winsocket编程的主要流程,从初始化、套接字创建、连接建立到数据交换和资源释放。通过实际编写和运行这些代码,你可以更直观地理解Winsocket的工作原理,并提升网络编程能力。 在第16章的...
Winsock是Windows操作系统对Berkeley套接字API(Socket API)的实现,它是跨平台通信协议的标准。在C++中,我们通常使用Winsock库来创建客户端和服务器端的网络应用程序,以实现数据的发送和接收。 要开始一个...
### WinSocket编程详解 ...以上函数覆盖了网络编程中的大多数需求,从套接字的创建、配置、连接管理到数据传输和错误处理等方面。通过这些函数,开发者能够构建复杂而高效的应用程序,无论是在TCP还是UDP协议层面上。
2. 创建套接字:使用`socket`函数创建一个套接字,指定其类型(如TCP或UDP)、协议和地址家族。 3. 绑定套接字:调用`bind`函数将套接字与本地IP地址和端口号关联。 4. 对于服务器端,监听连接请求:使用`listen`...
这一章可能扩展了第三章的内容,深入到Winsock 1的特定功能,如SOCKET结构、地址解析、套接字选项的更详细使用,以及在网络编程中常见的问题和解决方案。 **第五章 Windows Socket 2的扩展特性** Winsock 2引入了...
此外,网络编程还涉及到异常处理、超时重试、安全套接层(SSL/TLS)加密、性能优化等多个方面。 总之,WinSocket编程是构建网络应用程序的关键技术,它为C++开发者提供了在网络环境中实现通信的工具。通过学习和...
在这个过程中,WinSocket API提供了一整套接口供开发者使用,如`socket()`用于创建套接字,`bind()`绑定本地地址,`listen()`监听连接请求,`accept()`接受连接,`connect()`建立连接,`send()`和`recv()`用于数据的...
总结来说,`基于WinSocket编程的客户端和服务器端通信程序`涉及到网络编程的基本操作,如套接字创建、绑定、监听、接受连接和数据传输。通过分析和实践`TCPServer.cpp`和`TCPClient.cpp`,开发者可以深入理解TCP/IP...
【互联网网络与套接字通信】是计算机网络编程中的核心概念,主要涉及到Windows操作系统下的Win32套接字(WinSocket)以及相关的编程技术。套接字是实现进程间网络通信的基本工具,起源于加州伯克利大学的Berkeley ...
Socket,中文常称为“套接字”,是网络通信中的一个抽象概念,它相当于网络上的通信端点。在TCP/IP模型中,一个Socket代表了IP地址和端口号的组合,用于标识网络上的唯一进程。Socket分为两种类型:流式Socket(SOCK...