在标准的 C 语言库(如 stdio.h)中,并没有一个叫做 sendstring 的原生函数。

(图片来源网络,侵删)
sendstring 这个名字通常出现在两种场景下:
- 特定平台或旧系统(如 DOS)的函数:在早期的操作系统,如 MS-DOS 的
conio.h库中,存在一个sendstring函数,它的作用是直接将字符串发送到控制台(屏幕),类似于puts()但功能更底层。 - 自定义函数:在网络编程中,
sendstring是一个非常常见的自定义函数(或宏)的命名,开发者为了方便,会自己写一个函数来封装send()系统调用,用于一次性发送一个以空字符结尾的字符串。
由于现代开发主要集中在网络编程,第二种场景(自定义函数)是目前最常见和最有意义的,我将重点讲解这个。
网络编程中的自定义 sendstring 函数
在网络编程中,我们使用 send() 函数来发送数据,但 send() 函数一次只能发送一个你指定长度的数据块(buffer 和 length),如果我们想发送一个完整的字符串("Hello, Server!\n"),我们需要:
- 获取字符串的长度(通常用
strlen())。 - 调用
send(),传入字符串的地址和长度。
这个过程很常用,所以程序员通常会把它封装成一个自己的函数,命名为 sendstring 或 send_str 等。

(图片来源网络,侵删)
为什么需要自定义 sendstring?
- 代码简洁:一行
sendstring(client_socket, "Hello");比写send(client_socket, "Hello", strlen("Hello"), 0);更简洁,可读性更高。 - 减少错误:手动计算
strlen并传入正确的长度是容易出错的,封装后可以避免重复代码和潜在的错误。 - 功能扩展:你可以在自定义函数里增加额外的逻辑,
- 在发送前加上字符串的长度(用于某些自定义协议)。
- 增加错误处理和重试机制。
- 在调试模式下打印出发送的内容。
如何实现一个 sendstring 函数?
下面是一个在 Linux/Unix 和 Windows (Winsock) 环境下都能使用的 sendstring 函数示例。
#include <stdio.h>
#include <string.h>
#include <sys/socket.h> // for send()
#include <unistd.h> // for write() (备用)
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
// 在 Windows 上使用前需要链接 Ws2_32.lib
// #pragma comment(lib, "Ws2_32.lib")
#else
// Linux/Unix 的类型定义
typedef int SOCKET;
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#define closesocket(s) close(s)
#endif
/**
* @brief 发送一个以空字符结尾的字符串到指定的套接字。
*
* @param sock 目标套接字描述符。
* @param str 要发送的字符串指针。
* @return int 成功返回发送的字节数,失败返回 SOCKET_ERROR。
*/
int sendstring(SOCKET sock, const char *str) {
if (sock == INVALID_SOCKET || str == NULL) {
return SOCKET_ERROR;
}
size_t len = strlen(str);
// send() 可能不会一次性发送所有数据,需要循环发送
// 但对于大多数简单的客户端/服务器应用,一次性发送成功是常态
// 为了更健壮,应该实现一个循环发送的版本,下面会展示
int bytes_sent = send(sock, str, len, 0);
if (bytes_sent == SOCKET_ERROR) {
perror("send failed");
return SOCKET_ERROR;
}
return bytes_sent;
}
// --- 更健壮的循环发送版本 ---
int sendstring_robust(SOCKET sock, const char *str) {
if (sock == INVALID_SOCKET || str == NULL) {
return SOCKET_ERROR;
}
size_t total_len = strlen(str);
size_t sent_len = 0;
int bytes_sent;
// 循环直到整个字符串发送完毕
while (sent_len < total_len) {
bytes_sent = send(sock, str + sent_len, total_len - sent_len, 0);
if (bytes_sent == SOCKET_ERROR) {
perror("send failed");
return SOCKET_ERROR;
}
if (bytes_sent == 0) {
// 对方关闭了连接
break;
}
sent_len += bytes_sent;
}
return sent_len;
}
如何使用 sendstring 函数?
下面是一个简单的 TCP 客户端示例,展示如何使用上面的 sendstring 函数。
// 这是一个完整的客户端示例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// ... (包含上面 sendstring 函数的代码) ...
int main() {
#ifdef _WIN32
// Windows 初始化 Winsock
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0) {
printf("WSAStartup failed: %d\n", result);
return 1;
}
#endif
// 1. 创建套接字
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == INVALID_SOCKET) {
perror("socket creation failed");
#ifdef _WIN32
WSACleanup();
#endif
return 1;
}
// 2. 设置服务器地址
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080); // 监听端口
// 将 "127.0.0.1" 转换为网络地址
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
// 3. 连接服务器
if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
perror("connect failed");
closesocket(client_socket);
#ifdef _WIN32
WSACleanup();
#endif
return 1;
}
printf("Connected to server!\n");
// 4. 使用 sendstring 发送消息
const char *message1 = "Hello, Server! This is message 1.\n";
const char *message2 = "How are you?\n";
if (sendstring(client_socket, message1) == SOCKET_ERROR) {
printf("Failed to send message 1\n");
} else {
printf("Sent message 1: %s", message1);
}
if (sendstring(client_socket, message2) == SOCKET_ERROR) {
printf("Failed to send message 2\n");
} else {
printf("Sent message 2: %s", message2);
}
// 5. 关闭套接字
closesocket(client_socket);
#ifdef _WIN32
WSACleanup();
#endif
return 0;
}
DOS/旧系统中的 sendstring
如果你是在学习非常古老的 C 语言(Turbo C/C++ for DOS),你可能会在 conio.h 头文件中找到 sendstring。
- 头文件:
conio.h(Console Input/Output) - 函数原型:
void sendtext(const char *str);(注意,有时叫sendtext,功能相同) - 功能: 直接将字符串
str输出到控制台屏幕上,光标会自动移动到字符串末尾。 - 与
puts()的区别:puts(str): 是标准 C 库函数,会输出字符串,然后自动换行。sendtext(str): 是非标准的 DOS 特有函数,输出字符串,但不会自动换行。
DOS 环境下的示例
#include <conio.h> // 包含 sendtext
int main() {
clrscr(); // 清屏,也是 conio.h 中的函数
cprintf("This is a line from cprintf.\n"); // cprintf 不会自动换行,需要手动加 \n
sendtext("This is a line from sendtext. "); // sendtext 也不会自动换行
getch(); // 等待用户按一个键
return 0;
}
| 特性 | 网络编程中的自定义 sendstring |
DOS 中的 sendstring (或 sendtext) |
|---|---|---|
| 来源 | 程序员自定义,非标准库 | 旧系统库 (conio.h),非标准 |
| 用途 | 通过网络套接字发送字符串数据 | 向控制台屏幕直接输出字符串 |
| 依赖 | 操作系统的网络 API (send, WSASend) |
DOS 操作系统的控制台 I/O |
| 平台 | Windows (Winsock), Linux/Unix 等 | MS-DOS, Turbo C 环境 |
| 核心逻辑 | 封装 send() 调用,处理字符串长度 |
直接调用底层 BIOS 或系统调用来写屏 |
在现代 C 语言编程中,当你看到 sendstring 时,99% 的情况都是指网络编程中用于发送字符串的自定义函数,理解它如何封装 send() 以及为什么要这样做,对于掌握网络编程非常重要。

(图片来源网络,侵删)
