实现以太网调试器功能的方法
实现以太网调试器功能的方法
网上有很多串口调试器,用UDP协议实现了一个Windows平台上的以太网调试器,用的是WinSock,也很方便的移植到装有socket的其他平台上。
程序思路实现很简单,初始化创建套接字,绑定,创建一个监听线程,用来接收远方计算机发送来的内容。源程序如下,是一个控制台程序,需要经常改动的地方已标记在注释中:
//发送给对方计算机的IP地址:(经常改动)
#define SENDTO_IP_ADDR "192.168.0.199"
//准备发送的内容:(经常改动)
#define SEND_STRING "lksjadkfjgad123456756544"
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include "windows.h"
#include <winsock2.h>
#include "conio.h"
#pragma comment(lib,"ws2_32.lib") //编译链接包含必要的库
DWORD WINAPI ThreadFunc( LPVOID lpParam ); //接收线程函数
struct sockaddr_in local, from,server;
WSADATA wsaData;
int fromlen;
SOCKET listen_socket;
int retval;
unsigned char Buffer[500]; //接收用缓冲区
DWORD dwThreadId, dwThrdParam = 1;
HANDLE hThread;
void send_buf(char *buf,int len);
int main()
{
char ch;
char strBuf[100]=SEND_STRING;
//初始化Winsock库
if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR)
{
fprintf(stderr,"WSAStartup failed with error %d/n",WSAGetLastError());
WSACleanup();
return -1;
}
//创建套接字
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY; //监听任何
local.sin_port = htons(1999);
listen_socket = socket(AF_INET, SOCK_DGRAM,0);
if (listen_socket == INVALID_SOCKET)
{
fprintf(stderr,"socket() failed with error %d/n",WSAGetLastError());
WSACleanup();
return -1;
}
//欲发送的对方设置
server.sin_family=AF_INET;
server.sin_port=htons(1999);
server.sin_addr.S_un.S_addr=inet_addr(SENDTO_IP_ADDR);
//绑定
if (bind(listen_socket,(struct sockaddr*)&local,sizeof(local))== SOCKET_ERROR)
{
fprintf(stderr,"bind() failed with error %d/n",WSAGetLastError());
WSACleanup();
return -1;
}
fromlen =sizeof(from);
//创建起一个线程,用来接收收到的数据
hThread = CreateThread(
NULL, // no security attributes
0, // use default stack size
ThreadFunc, // thread function
&dwThrdParam, // argument to thread function
0, // use default creation flags 如果该参数为0,线程就会立即开始执行
&dwThreadId); // returns the thread identifier
// Check the return value for success.
if (hThread == NULL)
{
printf("create thread error!/n");
return 0;
}
else
{
CloseHandle( hThread );
}
//进入主线程
while (1)
{
if(kbhit())
{
ch=_getch();
if(ch=='q'||ch=='Q'||(int)ch==27) //按‘q’键或“ESC”退出
break;
if(ch==' ') //按空格键发出数据
{
printf("/n已经发送:%s/n",strBuf);
send_buf(strBuf,100);
}
}
}
return 0;
}
//线程函数
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
while(1)
{
//接收
retval = recvfrom(listen_socket,(char *)Buffer,sizeof(Buffer),0,(struct sockaddr *)&from,&fromlen); // from已经接收了所收到数据方的信息
if (retval == SOCKET_ERROR)
{
fprintf(stderr,"recv() failed: error %d/n",WSAGetLastError());
closesocket(listen_socket);
continue;
}
if (retval == 0)
{
printf("Client closed connection/n");
closesocket(listen_socket);
continue;
}
printf("收到: %d 字节, data [%s] 来自客户方/n",retval,Buffer);
}
}
//发送函数封装
void send_buf(char *buf,int len)
{
sendto(listen_socket,buf,len,0,(struct sockaddr *)&server,sizeof(server));
}