You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于C语言Socket端口扫描器中strncpy作用的技术问询

Hey there! Nice work diving into socket programming and port scanners—hands-on projects like this are the best way to learn. Let's break down strncpy and how it fits into your port scanner code, since I remember being confused by this exact function when I started out too.

First, let's cover the basics of strncpy, then we'll tie it to common port scanner scenarios you might have encountered.

What is strncpy, anyway?

strncpy is a C standard library function (from <string.h>) made for copying strings safely (well, safer than its risky cousin strcpy). The problem with strcpy is that it copies characters until it hits a null terminator (\0)—if your source string is longer than the destination buffer, it'll write past the buffer's end, causing buffer overflows that crash your program or create security holes.

strncpy fixes this by letting you specify a maximum number of characters to copy. Its signature is:

char *strncpy(char *dest, const char *src, size_t n);
  • dest: The buffer you're copying into
  • src: The string you're copying from
  • n: The maximum number of characters to copy

Critical things to remember:

  • If the source string is shorter than n, the remaining space in dest gets filled with null terminators.
  • If the source string is longer than n, it copies exactly n characters and does NOT add a null terminator to dest. That means you have to manually add a \0 if you want dest to be a valid C string later—this is a super common beginner mistake!

How strncpy is used in port scanners

Let's look at a typical snippet you might have found in a basic port scanner. A common use case is safely handling user input (like a target IP or hostname) to avoid buffer overflows. Here's a realistic example:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// Function to scan a single port
void scan_single_port(const char *target_ip, int port) {
    int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0) {
        perror("Failed to create socket");
        return;
    }

    struct sockaddr_in target_addr;
    memset(&target_addr, 0, sizeof(target_addr)); // Zero out the struct
    target_addr.sin_family = AF_INET;
    target_addr.sin_port = htons(port); // Convert port to network byte order

    // Convert IP string to binary format for the socket struct
    if (inet_pton(AF_INET, target_ip, &target_addr.sin_addr) <= 0) {
        perror("Invalid IP address");
        close(sock_fd);
        return;
    }

    // Try connecting to the port
    if (connect(sock_fd, (struct sockaddr *)&target_addr, sizeof(target_addr)) == 0) {
        printf("Port %d is OPEN\n", port);
    }

    close(sock_fd);
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s <target-ip> <starting-port>\n", argv[0]);
        return 1;
    }

    // Safely copy the target IP from command line into a fixed-size buffer
    char target_ip_buffer[INET_ADDRSTRLEN]; // Macro for max IPv4 string length (16 chars)
    strncpy(target_ip_buffer, argv[1], sizeof(target_ip_buffer) - 1);
    target_ip_buffer[sizeof(target_ip_buffer) - 1] = '\0'; // Manually add null terminator

    int start_port = atoi(argv[2]);
    // Scan 10 ports starting from the given port
    for (int port = start_port; port < start_port + 10; port++) {
        scan_single_port(target_ip_buffer, port);
    }

    return 0;
}

Breaking down the strncpy part here:

  1. Why not just use strcpy?
    The user could pass a super long string as argv[1] (by accident or on purpose). If we used strcpy(target_ip_buffer, argv[1]), and that string was longer than 16 characters, we'd overwrite memory beyond the buffer—this is a buffer overflow, which is bad news for stability and security.

  2. What's with sizeof(target_ip_buffer) - 1?
    We leave one byte empty so we can manually add a null terminator. Remember: if the input string is longer than 15 characters, strncpy will copy 15 characters and stop, no \0 included. By setting the last byte to \0, we make sure target_ip_buffer is always a valid, null-terminated C string, even if the input was too long.

  3. Are there safer alternatives?
    For modern C, you might see snprintf used instead, like:

    snprintf(target_ip_buffer, sizeof(target_ip_buffer), "%s", argv[1]);
    

    This automatically adds a null terminator, so you don't have to remember to do it manually. But strncpy is still everywhere in legacy network code, so it's important to understand how it works.

Quick recap for your port scanner

  • Use strncpy to safely copy strings into fixed-size buffers to avoid buffer overflows.
  • Always manually add a null terminator after using strncpy unless you're 100% sure the source string is shorter than the buffer.
  • In port scanners, this is most often used to handle user input (target IP/hostname) or service names (like "http" instead of port 80) safely.

If you have the exact code snippet you found, feel free to share it and we can dig into the specifics even more!

内容的提问来源于stack exchange,提问作者Khalil Beldi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:12:11