我有以下情况:
Java程序调用C ++程序来捕获和返回网络数据包。 C ++程序在其上设置了特殊权限以允许网络数据包捕获。这两个程序通过TCP套接字进行通信。 Java程序发送一个简单的文本命令来告诉C ++程序它想要什么。 C ++程序捕获数据包并将它们发送回套接字。
套接字正在成功建立,初始信息正在进行中。当C ++程序连接套接字时,它发送一个简单的“准备好”,让Java程序知道它已连接并准备就绪。然后,Java程序发送其第一个命令来收集一些数据包。这些短信已成功发送和接收。
C ++程序捕获数据包并将它们发送到套接字(字节集合)。我通过查看Wireshark的流量来验证这一点。但是,在使用Control-C终止C ++程序之前,Java程序似乎没有收到任何此类数据。此时,Java程序打印出它收到的数据(尽管它似乎没有收到所有已发送的数据)。
我不明白什么似乎阻碍了信息的流动。我错过了什么?
更新:
根据要求,我在C ++和Java代码下面包含。
C ++:[建议关注openSocket
,send
和capture
函数
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cerrno>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "PacketCapture.h"
#define SNAP_SIZE 8192
#define COMMS_BUF_SIZE 256
struct capture_data
{
int length;
u_char* buffer;
};
bool openSocket(const std::string address, const int port);
void cleanUp(void);
int send(void *buffer, int length);
void capture(const int count, const std::string filter);
void split(char *value, const char *delimSet, std::vector<std::string> &list);
std::string printCaptureStatus(const int status);
void printPayload(const u_char *payload, int length);
void printHexASCIILine(const u_char *payload, int length, int offset);
int g_sock;
PacketCapture *g_pcap;
int main(int argc, char *argv[])
{
if (argc != 5) {
std::cerr << "Usage: " << argv[0] << " <address> <port> <device> <timeout>"
<< std::endl;
std::exit(1);
}
std::string address = argv[1];
int port = atoi(argv[2]);
std::string device = argv[3];
int timeout = atoi(argv[4]);
std::cout << "address: " << address << std::endl;
std::cout << "port: " << port << std::endl;
std::cout << "device: " << device << std::endl;
std::cout << "timeout: " << timeout << std::endl;
g_pcap = new PacketCapture(device, SNAP_SIZE, timeout);
if (g_pcap == NULL) {
std::cerr << "Could not create packet capture" << std::endl;
std::exit(1);
}
if (!openSocket(address, port)) {
std::cerr << "Could not create socket" << std::endl;
std::exit(1);
}
char buffer[COMMS_BUF_SIZE];
std::vector < std::string > tokens;
while (true) {
memset(buffer, 0, COMMS_BUF_SIZE);
int received = recv(g_sock, buffer, COMMS_BUF_SIZE, 0);
if (received > 0) {
std::cout << "received: " << buffer << std::endl;
tokens.clear();
split(buffer, "#\n", tokens);
std::cout << tokens.size() << " tokens" << std::endl;
for (std::vector<std::string>::iterator it = tokens.begin();
it != tokens.end(); ++it) {
std::cout << "'" << *it << "'" << std::endl;
}
if (tokens[0].compare("STOP") == 0) {
std::cout << "stopping" << std::endl;
break;
}
if (tokens[0].compare("CAPTURE") == 0) {
int count = atoi(tokens[1].c_str());
std::string filter = tokens[2];
std::cout << "capture: count: " << count << ", filter: " << filter
<< std::endl;
capture(count, filter);
}
} else {
// TODO error condition
}
usleep(1000);
}
cleanUp();
exit(0);
}
void cleanUp(void)
{
g_pcap->close();
delete g_pcap;
close(g_sock);
}
bool openSocket(const std::string address, const int port)
{
g_sock = 0;
struct sockaddr_in server_addr;
if ((g_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cerr << "Socket creation error" << std::endl;
return false;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
// Convert IPv4 and IPv6 addresses from text to binary form.
if (inet_pton(AF_INET, address.c_str(), &server_addr.sin_addr) <= 0) {
std::cerr << "Invalid address/ Address not supported" << std::endl;
return false;
}
if (connect(g_sock, (struct sockaddr *) &server_addr, sizeof(server_addr))
< 0) {
std::cerr << "Connection Failed" << std::endl;
return false;
}
char* ready = "READY";
send(ready, strlen(ready));
return true;
}
int send(void *buffer, int length)
{
int result = send(g_sock, buffer, length, 0);
if (result < 0) {
std::cerr << strerror(errno) << std::endl;
}
return result;
}
void capture(const int count, const std::string filter)
{
std::vector<struct capture_data> captureList;
g_pcap->setFilter(filter);
u_char data[SNAP_SIZE];
int length = 0;
int status = 0;
for (int i = 0; i < count; i++) {
status = g_pcap->capturePacketData(data, &length);
std::cout << "capture: " << (i + 1) << ", status: "
<< printCaptureStatus(status) << ", length: " << length << std::endl;
printPayload(data, length);
if (status == 1 && length > 0) {
struct capture_data capture;
capture.length = length;
capture.buffer = data;
captureList.push_back(capture);
}
}
std::cout << "capture count: " << captureList.size() << std::endl;
// Send number of captures.
int size = captureList.size();
send(&size, sizeof(int));
for (int i = 0; i < captureList.size(); i++) {
struct capture_data capture = captureList[i];
std::cout << "sending" << std::endl;
// Send the capture data length.
send(&(capture.length), sizeof(int));
// Send capture data.
int numSent = send(capture.buffer, capture.length);
std::cout << "sent: " << numSent << std::endl;
}
}
std::string printCaptureStatus(const int status)
{
switch (status) {
case 0:
return "TIMEOUT";
case 1:
return "OK";
case -1:
return "ERROR";
case -2:
return "EOD";
default:
return "UNKNOWN";
}
}
void split(char *value, const char *delimSet, std::vector<std::string> &list)
{
char *ptr = strtok(value, delimSet);
while (ptr != NULL) {
list.push_back(ptr);
ptr = strtok(NULL, delimSet);
}
}
void printPayload(const u_char *payload, int length)
{
int len_rem = length;
int line_width = 16; /* number of bytes per line */
int line_len;
int offset = 0; /* zero-based offset counter */
const u_char *ch = payload;
if (length <= 0) {
return;
}
/* data fits on one line */
if (length <= line_width) {
printHexASCIILine(ch, length, offset);
return;
}
/* data spans multiple lines */
while (true) {
/* compute current line length */
line_len = line_width % len_rem;
/* print line */
printHexASCIILine(ch, line_len, offset);
/* compute total remaining */
len_rem = len_rem - line_len;
/* shift pointer to remaining bytes to print */
ch = ch + line_len;
/* add offset */
offset = offset + line_width;
/* check if we have line width chars or less */
if (len_rem <= line_width) {
/* print last line and get out */
printHexASCIILine(ch, len_rem, offset);
break;
}
}
return;
}
void printHexASCIILine(const u_char *payload, int length, int offset)
{
int i;
int gap;
const u_char *ch;
/* offset */
printf("%06x ", offset);
/* hex */
ch = payload;
for (i = 0; i < length; i++) {
printf("%02x ", *ch);
ch++;
/* print extra space after 8th byte for visual aid */
if (i == 7) {
printf(" ");
}
}
/* print space to handle line less than 8 bytes */
if (length < 8) {
printf(" ");
}
/* fill hex gap with spaces if not full line */
if (length < 16) {
gap = 16 - length;
for (i = 0; i < gap; i++) {
printf(" ");
}
}
printf(" ");
/* ASCII (if printable) */
ch = payload;
for (i = 0; i < length; i++) {
if (isprint(*ch)) {
printf("%c", *ch);
} else {
printf(".");
}
ch++;
}
printf("\n");
return;
}
爪哇:
package xyz;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.List;
import xyz.HexDump;
public class TestCapture {
private static final int PORT = 9000;
private static ServerSocket serverSocket;
private static Socket clientSocket;
// private static BufferedReader input;
private static InputStream input;
private static PrintWriter output;
public static void main(String[] args) {
initSocket();
process();
close();
}
private static void initSocket() {
try {
System.out.println("waiting for connection");
serverSocket = new ServerSocket(PORT);
clientSocket = serverSocket.accept();
// input = new BufferedReader(new
// InputStreamReader(clientSocket.getInputStream()));
input = clientSocket.getInputStream();
output = new PrintWriter(clientSocket.getOutputStream(), true);
// should be "READY"
byte[] data = new byte[8192];
receiveData(data);
String response = new String(data);
System.out.println(response);
System.out.println("accepted connection");
System.out.println("port: " + clientSocket.getPort() + ", local port: " + clientSocket.getLocalPort());
} catch (IOException e) {
e.printStackTrace();
}
}
private static void process() {
try {
// byte[] data = new byte[8192];
// for (int i = 0; i < 10; i++) {
output.println("CAPTURE#20#tcp port 61616");
// int numBytes = receiveData(data);
// System.out.println("received: " + numBytes);
// System.out.println(HexDump.dump(data, numBytes, 16, true));
List<CaptureInfo> captures = receiveData();
System.out.println("captures: " + captures.size());
for (int i = 0; i < captures.size(); i++) {
CaptureInfo info = captures.get(i);
System.out.println("capture: " + (i + 1) + ", length: " + info.length);
System.out.println(HexDump.dump(info.data, info.length, 16, true));
}
// }
output.println("STOP");
} catch (IOException e) {
e.printStackTrace();
}
}
private static int receiveData(byte[] data) {
int numBytes = 0;
try {
numBytes = input.read(data);
} catch (IOException e) {
e.printStackTrace();
}
return numBytes;
}
private static List<CaptureInfo> receiveData() {
List<CaptureInfo> result = new LinkedList<CaptureInfo>();
byte[] data = new byte[8192];
int numBytes = 0;
while (numBytes != -1) {
try {
numBytes = input.read(data);
} catch (IOException e) {
e.printStackTrace();
}
if (numBytes >= 0) {
result.add(new CaptureInfo(numBytes, data));
} else {
System.out.println("EOD");
}
}
return result;
}
private static void close() {
try {
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static class CaptureInfo {
int length;
byte[] data;
CaptureInfo(int length, byte[] data) {
this.length = length;
this.data = data;
}
}
}