🎓 BookMCQ
← Back to 27. Network Management

📝 ASN.1 data types explained (23 MCQs)

📖 From Data Communication and Networks • 27. Network Management • 23 questions available

What is ASN.1 data types explained?

ASN.1 provides primitive types like BOOLEAN, INTEGER, and OCTET STRING for simple values, and constructed types like SEQUENCE, SET, and CHOICE for grouping data; it also includes specialized SNMP types such as Counter32, Gauge32, and IpAddress to represent network-specific information precisely.

7
Easy
10
Medium
6
Hard

📝 All ASN.1 data types explained MCQs

Q1. In the server code, variable `int s;` holds the socket descriptor. If the program mistakenly declares it as `float s;`, what immediate effect would occur when `socket()` returns a large integer value?

A.The value would be truncated, causing an invalid descriptor ✅
B.The value would be stored correctly because of implicit conversion
C.The program would crash at compile time
D.The descriptor would be interpreted as a floating‑point number, leading to undefined behavior
💡 Difficulty: easy | ✅ Correct: A

📖 Explanation: Using a floating‑point type for a descriptor causes the large integer returned by `socket()` to be converted to a floating‑point representation, losing precision and potentially yielding a negative or non‑integer value. Subsequent system calls expect a valid integer descriptor, so the program will likely fail to communicate or produce errors.

Q2. Why does the client program use `char *servName;` instead of `char servName[256];` when handling command‑line arguments?

A.Because the length of the server name is unknown at compile time
B.Because pointers allow direct modification of the argument string
C.Because arrays cannot be passed to functions
D.Because `char *` automatically allocates memory on the heap ✅
💡 Difficulty: easy | ✅ Correct: D

📖 Explanation: The command‑line argument is already stored in memory by the runtime; assigning a `char *` simply points to that existing string. Using a fixed‑size array would require copying the data, which is unnecessary and could waste stack space if the name is short. Hence the pointer is the most efficient choice.

Q3. If `int n;` is used to store the number of bytes received from `recv()`, what logical error could arise if `n` is later compared to a constant defined as `#define MAX 256` using the expression `if (n > MAX)`?

A.The comparison will always be true because `int` is signed ✅
B.The comparison may be false if `n` wraps around due to overflow
C.The comparison is correct; no logical error exists
D.The comparison could be misleading if `n` is negative, indicating an error condition
💡 Difficulty: medium | ✅ Correct: A

📖 Explanation: `recv()` returns a negative value on error. Storing that in a signed `int` and then testing `n > MAX` would treat an error as a valid byte count, potentially causing the program to process invalid data. Proper error checking should test for `n < 0` before any size comparison.

Q4. Consider the line `char buffer[256 + 1];`. Which reasoning best explains the use of `+ 1` in this declaration?

A.To store a null‑terminator for a C‑string
B.To align the buffer on a 4‑byte boundary
C.To provide space for the length field of a TCP segment ✅
D.To reserve extra space for future protocol extensions
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: The buffer is intended for raw data transfer, not null‑terminated strings, so the extra byte is not for a terminator. However, many protocols prepend a length byte or need a sentinel value; allocating one more byte anticipates such a requirement, ensuring the buffer can hold the maximum payload plus the additional control byte.

Q5. When the server declares `struct sockaddr_in serverAddr;`, what inference can be made about the type of network communication it intends to use?

A.It must be using IPv6 addresses
B.It is prepared for both TCP and UDP over IPv4 ✅
C.It can only handle raw sockets
D.It will use a custom protocol stack
💡 Difficulty: medium | ✅ Correct: B

📖 Explanation: `struct sockaddr_in` is the standard structure for IPv4 socket addresses, applicable to both stream (TCP) and datagram (UDP) sockets. Its presence indicates the program will operate over IPv4, but does not restrict the transport protocol; the later `listen` or `connect` calls determine TCP versus UDP.

Q6. If the server mistakenly writes `serverAddr.sin_family = AF_INET6;` while still using `struct sockaddr_in`, what deduction follows regarding the program’s behavior?

A.The server will communicate over IPv6 without changes
B.The program will fail to bind because the address family mismatches the structure size
C.The operating system will auto‑convert the address family ✅
D.The bind call will succeed but packets will be dropped
💡 Difficulty: hard | ✅ Correct: C

📖 Explanation: Assigning `AF_INET6` to a field designed for IPv4 does not automatically adjust the structure layout. The `bind` system call will interpret the mismatched family as an error, typically returning `EINVAL`. The program will not start listening, highlighting the importance of matching address families with their corresponding structures.

Q7. Why is the pointer `char *ptr = buffer;` introduced after the buffer declaration, and what logical effect does advancing `ptr` have during data reception?

A.It allows the program to modify the original buffer pointer ✅
B.It enables sequential writing into the buffer without overwriting previous bytes
C.It creates a separate copy of the buffer for thread safety
D.It provides a way to free the buffer later
💡 Difficulty: medium | ✅ Correct: A

📖 Explanation: `ptr` is initialized to the start of `buffer` and then incremented as bytes are received. This technique lets the program write incoming data to successive locations while preserving the original buffer address for later processing or printing. Advancing `ptr` does not modify `buffer` itself; it merely changes where the next write occurs.

Q8. Compare the use of `int` for socket descriptors with using `void *` as a generic handle. Which analytical conclusion is most accurate?

A.`void *` provides better type safety for descriptors
B.`int` allows arithmetic on descriptors, which is useful
C.`int` is the conventional and portable type for descriptors ✅
D.Both are equivalent in practice
💡 Difficulty: easy | ✅ Correct: C

📖 Explanation: Socket descriptors are defined by the POSIX API as integer values. Using `int` aligns with the standard, ensuring portability across platforms. A `void *` would require casting and could obscure the nature of the descriptor, potentially leading to misuse or compilation warnings. Therefore, `int` remains the preferred choice.

Q9. Evaluate the impact of declaring `char *string;` without allocating memory before assigning `string = argv[3];`. Which statement best reflects the program’s safety?

A.It is unsafe because `argv[3]` may be null
B.It is safe because `argv[3]` points to a valid string supplied by the user ✅
C.It is unsafe because `string` should be a fixed‑size array
D.It is safe only if the program later copies the string into a buffer
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: `argv[3]` is provided by the runtime and points to a null‑terminated string from the command line. Assigning its address to `string` does not copy the data but merely references it. As long as the program does not modify the string or exceed its length, this usage is safe and common in C programs.

Q10. The server code uses `memset(&servAddr, 0, sizeof(servAddr));`. What conceptual reason justifies zero‑initializing this structure before setting fields?

A.It clears any residual data that could cause undefined behavior ✅
B.It improves performance by aligning memory
C.It encrypts the structure for security
D.It signals the OS that the address is uninitialized
💡 Difficulty: medium | ✅ Correct: A

📖 Explanation: Zero‑initializing ensures that all fields not explicitly set (such as padding bytes) contain known values, preventing accidental leakage of garbage data into system calls like `bind`. This practice avoids undefined behavior that could arise from uninitialized fields, especially on architectures where padding may be transmitted.

Q11. Synthesize a scenario where changing `char buffer[256 + 1];` to `char buffer[512];` could introduce a subtle bug in the client program. Which explanation is most plausible?

A.The larger buffer may cause stack overflow on embedded systems
B.The extra space will be ignored by the network stack
C.The program will read beyond the intended length, exposing stale data ✅
D.The change has no effect on program correctness
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: Increasing the buffer size without adjusting the logic that tracks the number of valid bytes can lead to processing of uninitialized memory. If the program assumes the buffer contains only the received payload, residual data from previous operations may be mistakenly transmitted or printed, causing incorrect output.

Q12. If the client incorrectly declares `int servPort;` but later assigns `servPort = atoi(arg[2]);` where `arg[2]` is a non‑numeric string, what logical mistake does this represent?

A.Failing to check for conversion errors before using the value ✅
B.Assuming `atoi` returns -1 on failure
C.Using a signed integer for a port number
D.Neglecting to free the allocated memory for `servPort`
💡 Difficulty: medium | ✅ Correct: A

📖 Explanation: `atoi` returns 0 when conversion fails, which is a valid (though usually undesired) port number. Not checking the result can cause the client to attempt a connection on an unintended port, leading to connection failures or unintended behavior. Proper error handling should verify that the conversion succeeded and the result lies within the valid port range.

Q13. Analyze the effect of declaring `struct sockaddr_in serverAddr;` as a global variable versus a local variable inside `main()`. Which outcome best reflects the difference?

A.Global scope guarantees the structure is zeroed at program start
B.Local scope reduces the risk of accidental modification by other functions
C.Global scope can lead to thread‑safety issues in multi‑threaded servers
D.Both B and C are correct ✅
💡 Difficulty: medium | ✅ Correct: D

📖 Explanation: Placing the address structure globally makes it accessible to any function, which could unintentionally modify its fields, especially in multi‑threaded contexts. Declaring it locally confines its lifetime to `main`, reducing side effects and improving encapsulation. However, both scopes can be zeroed explicitly, so the primary concerns are encapsulation and thread safety.

Q14. When the server uses `int n;` to store the return value of `recv()`, why might a developer prefer `ssize_t n;` instead?

A.`ssize_t` is always unsigned, preventing negative values
B.`ssize_t` matches the exact return type of `recv` and can represent larger byte counts ✅
C.`ssize_t` automatically checks for buffer overflows
D.`ssize_t` is more portable across Windows and Unix
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: The POSIX `recv` function returns a signed size type (`ssize_t`) that can represent both the number of bytes read and negative error codes. Using `ssize_t` ensures the variable can hold the full range of possible return values without truncation, improving correctness and portability.

Q15. If the server mistakenly changes `char buffer[256 + 1];` to `char buffer[256];` but still writes a null terminator after the received data, what consequence follows?

A.The null terminator will overwrite the last data byte, corrupting the message
B.The program will write beyond the allocated memory, causing undefined behavior ✅
C.The null terminator will be ignored by the client
D.No consequence, because the buffer size matches the maximum payload
💡 Difficulty: hard | ✅ Correct: B

📖 Explanation: Writing a null terminator at `buffer[length]` when the buffer size equals the maximum payload (256) writes to index 256, which is outside the allocated array (indices 0‑255). This out‑of‑bounds write can corrupt adjacent memory, leading to crashes or security vulnerabilities.

Q16. Explain why `int s;` is preferred over `unsigned int s;` for a socket descriptor, considering potential system call semantics. Which conceptual point is most accurate?

A.Socket descriptors can be negative to indicate errors
B.Unsigned integers have larger range, which is unnecessary
C.System calls expect signed integers for descriptor arguments
D.Both A and C are true ✅
💡 Difficulty: hard | ✅ Correct: D

📖 Explanation: POSIX defines socket descriptors as non‑negative integers, but functions like `socket()` return `-1` on error. Using a signed `int` allows the program to detect this error condition directly. An unsigned type would wrap `-1` to a large positive value, obscuring the failure. Hence, signed `int` aligns with the API contract.

Q17. What logical reasoning explains why `char *ptr = buffer;` is used instead of directly indexing `buffer[i]` inside the receive loop?

A.It reduces the number of pointer arithmetic operations
B.It simplifies code by avoiding explicit index variables ✅
C.It enables the compiler to optimize memory accesses
D.It allows the same pointer to be passed to functions expecting a `char *`
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: Using a pointer that is incremented after each `recv` call eliminates the need for an explicit index variable, making the loop body shorter and clearer. The pointer always points to the next free position in the buffer, and the code can directly pass `ptr` to subsequent functions without calculating offsets.

Q18. Which factual statement correctly defines the purpose of `struct sockaddr_in` fields `sin_family`, `sin_port`, and `sin_addr`?

A.`sin_family` specifies the protocol, `sin_port` the host name, `sin_addr` the MAC address
B.`sin_family` indicates IPv4, `sin_port` holds the network‑order port, `sin_addr` contains the IPv4 address ✅
C.`sin_family` is always zero, `sin_port` is the socket descriptor, `sin_addr` is unused
D.All fields are optional and can be set to zero
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: `struct sockaddr_in` is the IPv4 socket address structure. `sin_family` must be set to `AF_INET` to indicate IPv4. `sin_port` stores the port number in network byte order, typically set using `htons`. `sin_addr` holds the IPv4 address, often set via `inet_pton` or `INADDR_ANY`. These fields together define where the socket will bind or connect.

Q19. In the client program, `int s;` is used for the socket descriptor. If the code were ported to a 64‑bit system where descriptors are 64‑bit values, what conceptual issue might arise?

A.`int` would truncate the descriptor, causing failures ✅
B.`int` automatically expands to 64‑bit on such systems
C.The program would compile without warnings
D.No issue, because descriptors are always 32‑bit
💡 Difficulty: medium | ✅ Correct: A

📖 Explanation: While most POSIX implementations keep socket descriptors as 32‑bit integers even on 64‑bit platforms, some systems may define them as larger types. Using a plain `int` could truncate a 64‑bit descriptor, leading to invalid handles and runtime errors. Portable code should use the `socket_t` or `int` as defined by the API, but awareness of potential size differences is essential.

Q20. When the server declares `int n;` and later uses `if (n == -1)`, what conceptual relationship between `n` and error handling does this illustrate?

A.`-1` indicates an end‑of‑file condition
B.`-1` is a sentinel for successful operation
C.`-1` signals a system call error, consistent with POSIX conventions ✅
D.`-1` has no special meaning and is arbitrary
💡 Difficulty: medium | ✅ Correct: C

📖 Explanation: POSIX system calls, including `recv()`, return `-1` to indicate an error, setting `errno` to describe the failure. Checking for `n == -1` follows this convention, allowing the program to handle errors appropriately. This pattern is fundamental to robust network programming.

Q21. Why might a programmer choose `size_t len;` instead of `int len;` for storing the length of a string to be echoed?

A.`size_t` ensures the length is always positive and matches the return type of `strlen` ✅
B.`size_t` is signed, allowing negative lengths for error codes
C.`size_t` is faster to compute than `int`
D.`size_t` automatically converts to network byte order
💡 Difficulty: hard | ✅ Correct: A

📖 Explanation: `size_t` is the unsigned type returned by `strlen` and other size‑related functions, guaranteeing a non‑negative value and accommodating the full range of possible string lengths on the target platform. Using `int` could truncate large lengths or permit negative values, which are semantically incorrect for a size.

Q22. If the client program replaces `char *servName;` with `char servName[128];` but forgets to copy the command‑line argument into the array, what logical error will result?

A.The program will attempt to connect using an empty string, causing a DNS failure ✅
B.The compiler will generate an error for uninitialized array
C.The socket will bind to an unintended port
D.The program will crash immediately
💡 Difficulty: hard | ✅ Correct: A

📖 Explanation: Without copying the provided hostname into `servName`, the array remains filled with zeros (or indeterminate data), leading to an empty or invalid hostname string. The subsequent `connect` call will fail to resolve the address, typically resulting in a DNS error and termination of the client.

Q23. Which factual definition accurately describes the role of `AF_INET` in the socket API?

A.It specifies the address family for IPv6 communications
B.It indicates the use of the Internet Protocol version 4 address family ✅
C.It is a flag that enables encryption on the socket
D.It determines the buffer size for socket operations
💡 Difficulty: easy | ✅ Correct: B

📖 Explanation: `AF_INET` is a constant defined in the sockets API that designates the IPv4 address family. It tells the system that the socket will use IPv4 addresses, influencing how address structures are interpreted and how routing is performed. It is distinct from `AF_INET6`, which is used for IPv6.

🔗 Related Topics (MCQs)