当前位置:首页 » 编程语言 » c语言中怎么截取tcp
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言中怎么截取tcp

发布时间: 2022-05-03 19:43:19

‘壹’ 怎么样用出c语言写一个分析TCP/IP报文的程

socket编程写了一个简单的DNS服务器。
是这样实现的,用两台PC,一个做客户端,一个做服务器;
在服务器用socket监视53端口,recvfrom()函数负责接收DNS查询报文,将其存入事先写好的数据结构里;
因为DNS查询报文和应答报文的前部分字段格式都是一样的,只是修改了几个参数,然后重点把DNS应答报文后面的字段进行增添。
然后用sendto();函数发送就可以了。
在ie里面输入任意的网址,回车,就会触发客户端向服务器发出DNS查询报文,
此时你可以同时在服务器和客户端抓包,看收到的报文是否正确。

注意几点:
1、一定要熟悉报文结构,定义合适的结构体,将报文进行解析
2、一定要注意网络序和主机序的转换htonl(),htons(),ntohl(),ntohs()等
3、找个熟知端口,最好是你熟悉的协议,如ftp,http,dns等。
4、客户端要把DNS服务器配置为你的服务器ip。

‘贰’ 关于tcp协议中服务端字符串的接受,截取和处理···

如果长度是固定的,可以根据长度判断,要是不固定的用数组形式发送,接受后分割数组,假如:
A|B|C,是个数组,接收后,分割数组,得到,A,B,C,再将A作为对比,B和C作为参数!
你用的是什么语言?

‘叁’ 怎样用c语言或者c++实现tcp,并实现文本传输

TCP协议实现文件传输

使用TCP协议实现传输文件
程序分为发送端和接收端。首先在传输文件数据之前,发送端会把将装有文件名称和文件长度等
信息的数据包发送至接收端。接收端收到文件名称和文件长度信息后会创建好空白文件。接着开始传输
文件数据。下面介绍实现功能的主要过程:

1.创建套接字、绑定、监听、连接、接受连接
//创建TCP协议的套接字
m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(SOCKET_ERROR == m_Socket)
AfxMessageBox("Create Socket Error! ", 0, 0);

//绑定与监听
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.s_addr = inet_addr(sIP);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(Port);
int ret = bind(m_Socket, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
if(ret==SOCKET_ERROR)
AfxMessageBox("Bind Socket Error!", 0, 0);

//连接
SOCKADDR_IN ServerAddr;
ServerAddr.sin_addr.s_addr = inet_addr(ServerAddr_in);
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(ServerPort);
int Result = connect(m_Socket, (struct sockaddr*)&ServerAddr, sizeof(struct sockaddr));
if(SOCKET_ERROR == Result)
AfxMessageBox("Connet Failed!");

//接受连接
SOCKADDR_IN ClientAddr;
int len = sizeof(SOCKADDR_IN);
SOCKET ClientSock = accept(m_Socket, (struct sockaddr*)&ClientAddr, &len);
if(SOCKET_ERROR == ClientSock)
AfxMessageBox("Accept Failed!");

2.声明宏和结构体
声明套接字缓冲区和一次发送文件数据的缓冲区大小
#define SOCKET_BUFF 80000 //套接字缓冲区大小
#define PACK_BUFF 50000 //数据包缓冲区大小

声明文件I/O缓冲区和最大文件路径长度
#define FILE_NAME_MAX 100 //文件路径最大长度
#define FILE_IO_BUFF PACK_BUFF //文件IO缓冲区

//文件信息
typedef struct _FileInfor
{
u_long ulFileLen;
char sFileName[ FILE_NAME_MAX ];
}_FileInfor;

//数据包
typedef struct _DataPack
{
char cType; //'D'为数据 'M'为文件信息
int nPackLen;
char sContent[ PACK_BUFF ]; //数据包缓冲区
u_long nPosition; //数据在文件中的位置
int nContentLen; //数据字节数
_FileInfor FileInfor; //文件信息
}_DataPack;

3.发送端
//发送线程需要的全局变量
char sPath[FILE_NAME_MAX]; //文件地址
u_long FileByteCount; //文件大小
SOCKET ClientSocket; //

(1)设置套接字发送缓冲区大小,在32位Windows XP环境下,系统为每个套接字分配的默认发送数据缓
冲区为8192字节。由于传输的文件很大,可能几十兆,或者更大。那么系统为每个套接字分配的默认
缓冲区显然过小。为此在创建套接字之后,需要修改套接字发送数据缓冲尺寸。在这里我修改为80k,
差不多可以够用了。
//设置套接字发送缓冲区
int nBuf = SOCKET_BUFF;
int nBufLen = sizeof(nBuf);
int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, nBufLen);
if(SOCKET_ERROR == nRe)
AfxMessageBox("setsockopt error!");
//检查缓冲区是否设置成功
nRe = getsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, &nBufLen);
if(SOCKET_BUFF != nBuf)
AfxMessageBox("检查缓冲区:setsockopt error!");

(2)测量文件大小并发送文件大小和名称给客户端

首先使用C库函数对源文件进行测量
//得到文件地址
LPTSTR lpPath = m_sPath.GetBuffer( m_sPath.GetLength ());
//打开文件
FILE *File = fopen(lpPath, "rb");
if(NULL == File)
AfxMessageBox("打开文件失败!");
//测量文件大小
char Buff[PACK_BUFF];
u_long ulFaceReadByte;
FileByteCount = 0;
fseek(File, 0, SEEK_SET);
while(!feof(File))
{
ulFaceReadByte = fread(Buff, 1, 1, File);
FileByteCount += ulFaceReadByte;
}
//关闭文件
int nRe = fclose(File);
if(nRe)
AfxMessageBox("关闭文件失败!");

此时以获取源文件的长度,我们将文件长度和文件名称放到数据包中,设置数据包为'M'类型。
//打包
_DataPack Pack;
Pack.cType = 'M';
Pack.nPackLen = sizeof(Pack);
//取得文件名
ZeroMemory(Pack.FileInfor.sFileName, FILE_NAME_MAX);
GetFIieNameFromPath(lpPath, Pack.FileInfor.sFileName);
Pack.FileInfor.ulFileLen = FileByteCount;

接着使用send()将打包完成的数据包发送给接收端,把发送线程的全局变量初始化,并创建发送线
程,文件数据将由发送线程负责发送
//发送数据包 文件大小和名称
nRe = send(m_ClientSockFd.fd_array[0], (char*)&Pack, Pack.nPackLen, 0);
if(SOCKET_ERROR == nRe)
AfxMessageBox("Send File Size Failed!");
//线程准备全局变量
strcpy(sPath, m_sPath);
ClientSocket = m_ClientSockFd.fd_array[0];
//启动线程发送文件
DWORD ID;
m_hSendThread = CreateThread(0, 0, SendDataThrad, 0, 0, &ID);

(3)发送文件数据线程。先打开源文件,为了一次读取大量数据将文件缓冲区设置为FILE_IO_BUFF大小,
然后将读取的数据打包并发送。这样不断地读、不断地发送,直到将整个文件发送完为止。

DWORD __stdcall CServerDlg::SendDataThrad(LPVOID LpP)
{
//打开文件
FILE *File = fopen(sPath, "rb");
if(NULL == File)
{
AfxMessageBox("SendDataThrad中打开文件失败!");
return 1;
}
//设置文件缓冲区
int nBuff = FILE_IO_BUFF;
if(setvbuf(File, (char*)&nBuff, _IOFBF, sizeof(nBuff)))
AfxMessageBox("设置文件缓冲区失败!");
//读取文件数据并发送
u_long ulFlagCount = 0; //记录读了多少数据
u_long FaceReadByte = 0; //一次实际读取的字节数
char sBuff[PACK_BUFF];
ZeroMemory(sBuff, PACK_BUFF);
fseek(File, 0, SEEK_SET);
while (!feof(File))
{
FaceReadByte = fread(sBuff, 1, PACK_BUFF, File);
//打包
_DataPack DataPack;
DataPack.cType = 'D';
DataPack.nPackLen = sizeof(DataPack);
DataPack.nContentLen = FaceReadByte;
CopyMemory(DataPack.sContent, sBuff, FaceReadByte);
DataPack.nPosition = ulFlagCount;
//发送
int nResult = send(ClientSocket, (char*)&DataPack, DataPack.nPackLen, 0);
if (SOCKET_ERROR == nResult)
{
AfxMessageBox("SendDataThrad中发送数据失败!");
}else
ulFlagCount += FaceReadByte; //记录发送字节数
}
AfxMessageBox("发送结束");
//关闭
int nRe = fclose(File);
if(nRe)
AfxMessageBox("SendDataThrad中关闭文件失败!");
return 0;
}

4.接收端
//接收线程用的全局变量
_FileInfor FileInfor; //文件信息
u_long ulWriteByte; //记录总共写入的字节
char lpPath[FILE_NAME_MAX]; //文件路径
char sFilePathAndName[FILE_NAME_MAX]; //完整的文件路径

(1)设置套接字接收缓冲区大小。
//设置套接字接收缓冲区
int nBuf = SOCKET_BUFF;
int nBufLen = sizeof(nBuf);
SOCKET ClientSock = m_Sock.GetSocket();
int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_RCVBUF, (char*)&nBuf, nBufLen);
if(SOCKET_ERROR == nRe)
AfxMessageBox("setsockopt error!");
//检查缓冲区是否设置成功
nRe = getsockopt(ClientSock, SOL_SOCKET, SO_RCVBUF, (char*)&nBuf, &nBufLen);
if(SOCKET_BUFF != nBuf)
AfxMessageBox("检查缓冲区:setsockopt error!");

(2)接收文件信息和文件数据线程。先判断数据包是属于文件信息还是文件类型,如果是文件信息就根
据信息创建空文件,如果是文件数据就将数据已追加的方式写进目的文件中。

DWORD __stdcall CClientDlg::ReceiveDataPro(LPVOID LpP)
{
CSocket_Win32 *pCSock = (CSocket_Win32*)LpP;
u_long ulWriteByteCount = 0;
while (1)
{
_DataPack DataPack;
ZeroMemory(&DataPack, sizeof(DataPack));
if(!(*pCSock).Receive(&DataPack, sizeof(DataPack)))
{
AfxMessageBox("Receive DataPack Failed!");
}
//判断数据包类型
if('M' == DataPack.cType) //包为文件信息
{
//接收文件信息
FileInfor.ulFileLen = DataPack.FileInfor.ulFileLen; //获取文件长度
strcpy(FileInfor.sFileName, DataPack.FileInfor.sFileName); //获取文件名称
//得到文件目录
char sFilePath[FILE_NAME_MAX];
ZeroMemory(sFilePath, FILE_NAME_MAX);
strcpy(sFilePath, lpPath);
strcat(sFilePath, FileInfor.sFileName);
strcat(sFilePathAndName, sFilePath); //保存完整的文件路径
//创建文件
SECURITY_ATTRIBUTES attr;
attr.nLength = FileInfor.ulFileLen;
attr.lpSecurityDescriptor = NULL;
HANDLE hRe = CreateFile(sFilePath, GENERIC_WRITE, FILE_SHARE_WRITE, &attr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(INVALID_HANDLE_VALUE == hRe)
AfxMessageBox("创建文件失败!");
bool bRe = ::CloseHandle(hRe);
//可以开始接受文件
bIsStartReceive = true;
}else if('D' == DataPack.cType) //包为文件数据
{
//打开文件
char sPath[FILE_NAME_MAX];
strcpy(sPath, sFilePathAndName);
FILE *File = fopen(sPath, "ab");
if(0 == File)
AfxMessageBox("打开文件失败!");
//设置文件缓冲区
int nBuff = FILE_IO_BUFF;
if(setvbuf(File, (char*)&nBuff, _IOFBF, sizeof(nBuff)))
AfxMessageBox("设置文件缓冲区失败!");
//定位文件
u_long nPosition = DataPack.nPosition;
int nRe = fseek(File, nPosition, SEEK_SET);
if(nRe)
AfxMessageBox("SendDataThrad中定位失败!");
//写文件
u_long nNumberOfBytesWritten = fwrite(&DataPack.sContent, 1, DataPack.nContentLen, File);
if(DataPack.nContentLen != nNumberOfBytesWritten)
AfxMessageBox("写文件失败!");
else
{
ulWriteByteCount += nNumberOfBytesWritten;
}
fflush(File); //清除文件缓冲区
//关闭文件
nRe = fclose(File);
if(nRe)
AfxMessageBox("关闭文件失败!");

if(ulWriteByteCount >= FileInfor.ulFileLen)
{
AfxMessageBox("接收结束");
break;
}
}
}
return 0;
}

‘肆’ Windows系统用C语言写TCP通信

#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
typedef struct{
SOCKET accpt;
int lock;
}Arg;
void *transfer(void *arg)
{
Arg * info = (Arg *)arg;
SOCKET clientSock;
char recvbuf[102];
char sendBuf[] = "10";
int ret;
memcpy(&clientSock,(void*)&info->accpt,sizeof(clientSock));
info->lock =1;
while (TRUE)
{
ret = send(clientSock,sendBuf,2,0);
if (ret == -1)
{
break;
}
ret = recv(clientSock,recvbuf,102,0);
printf("%s\n",recvbuf);
}
return (void *)0;
}
void* timer(void *arg)
{
time_t last = time(NULL);
time_t now;
int i = 20;
while(i--)
{
now = time(NULL);
if(now - last == 1)
{
printf("1s past!\n");
last = now;
}
Sleep(500);
}
printf("timer exit.\n");
return (void *)0;
}
int main(void) {
WSADATA wsaData;
SOCKET ListenSocket;
SOCKADDR_IN service,client;
int len = sizeof(client);
Arg argument;
pthread_t tid;
char sendBuf[] = "ID=2;WHAT=host";
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
printf("Error at WSAStartup()\n");
return 1;
}
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(27115);
if (bind( ListenSocket,
(SOCKADDR*) &service,
sizeof(service)) == SOCKET_ERROR) {
printf("bind() failed.\n");
closesocket(ListenSocket);
WSACleanup();
return 1;
}
if (listen( ListenSocket, 1 ) == SOCKET_ERROR) {
printf("Error listening on socket.\n");
closesocket(ListenSocket);
WSACleanup();
return 1;
}
argument.lock = 1;
printf("Waiting for client to connect...\n");
pthread_create(&tid,NULL,timer,NULL);
while(TRUE){
argument.accpt = accept( ListenSocket, (SOCKADDR*)&client, &len );
if (argument.accpt == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else {
printf("accept%s:%d\n",inet_ntoa(client.sin_addr),client.sin_port);
while (!argument.lock);
argument.lock = 0;
// sendto(argument.accpt,sendBuf,sizeof(sendBuf),0,(SOCKADDR*)&client,len);
pthread_create(&tid,NULL,transfer,&argument);
//send(AcceptSocket,sendBuf,sizeof(sendBuf),0);
}
}
// No longer need server socket
closesocket(ListenSocket);
WSACleanup();
return 0;
}

‘伍’ c语言运行结果如何截屏

1 使用系统截屏功能。

需要使用按键print screen.在键盘上印的是prt sc。
单独使用该键,会截整个屏幕,如果用alt+prt sc,则会截取当前窗口的部分。

截屏后,数据会报存在剪贴板中,这时可以打开系统画图工具,或者任意图形编辑工具,粘贴。即可得到截屏后的数据,保存成文件即可。如果需要裁剪,也可以在这类工具中操作。

2 使用工具进行截屏。
目前提供快捷截屏的软件很多,比如qq,搜狗输入法,搜狗浏览器等都有截屏工具提供。
比如qq默认的截屏快捷键是ctrl+alt+a。同时按下三个键,会发现鼠标箭头变成彩色,这时点击并选择需要截屏的区域,双击即可完成截屏,将图片保存在内存中。
也可以在截屏后,直接保存成文件。

‘陆’ 如何用tcpmp命令截完整的数据包

默认系统里边没有安装有tcpmp的,无法直接使用这里我们可以使用yum来直接安装它yuminstall-ytcpmp如果忘记了这个软件的用法,我们可以使用tcpmp--help来查看一下使用方法一般我们的服务器里边只有一个网卡,使用tcpmp可以直接抓取数据包,但是这样查看太麻烦了,所以都会添加参数来进行获取的。例如我截取本机(192.168.31.147)和主机114.114.114.114之间的数据tcpmp-n-ieth0host192.168.31.147and114.114.114.114还有截取全部进入服务器的数据可以使用以下的格式tcpmp-n-ieth0dst192.168.31.147或者服务器有多个IP可以使用参数tcpmp-n-ieth0dst192.168.31.147or192.168.31.157我们抓取全部进入服务器的TCP数据包使用以下的格式,大家可以参考下tcpmp-n-ieth0dst192.168.31.147or192.168.31.157andtcp从本机出去的数据包tcpmp-n-ieth0src192.168.31.147or192.168.31.157tcpmp-n-ieth0src192.168.31.147or192.168.31.157andport!22andtcp或者可以条件可以是or和and配合使用即可筛选出更好的结果。