int sendto(
SOCKET s, // 已創建的套接字描述符
const char FAR* buf, // 待發送數據緩衝區指針
int size, // 緩衝區長度 (字節數)
int flags, // 調用標志位,通常為0;可設MSG_DONTROUTE、MSG_OOB等
const struct sockaddr FAR* to, // 目標地址結構指針 (IP+端口)
int tolen // 目標地址結構大小
);
返回值:成功返回實際發送字節數;失敗返回SOCKET_ERROR,調用WSAGetLastError()獲取錯誤碼。
int accept(
int fd, // 監聽套接字描述符 (由socket()+bind()+listen()獲得)
struct sockaddr* addr, // 輸出參數:返回客戶端地址信息
socklen_t* len // 輸入輸出參數:輸入addr緩衝區大小,返回實際填寫大小
);
返回值:成功返回新的已連接套接字描述符 (用於與該客戶端通信);失敗返回-1,errno指示錯誤。原監聽套接字繼續監聽新連接。
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
SOCKET sockServer, sockClient;
SOCKADDR_IN addrServer, addrClient;
char recvBuf[100], sendBuf[100];
int len = sizeof(SOCKADDR);
// 1. 初始化Winsock
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
printf("WSAStartup failed: %d\n", WSAGetLastError());
return 1;
}
// 2. 創建流式套接字
sockServer = socket(AF_INET, SOCK_STREAM, 0);
if (sockServer == INVALID_SOCKET) {
printf("socket failed: %d\n", WSAGetLastError());
WSACleanup(); return 1;
}
// 3. 綁定地址端口
addrServer.sin_family = AF_INET;
addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 綁定所有本地接口
addrServer.sin_port = htons(6000); // 端口6000
if (bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)) == SOCKET_ERROR) {
printf("bind failed: %d\n", WSAGetLastError());
closesocket(sockServer); WSACleanup(); return 1;
}
// 4. 監聽
if (listen(sockServer, 5) == SOCKET_ERROR) { // 最大等待連接隊列5
printf("listen failed: %d\n", WSAGetLastError());
closesocket(sockServer); WSACleanup(); return 1;
}
printf("服務器已啟動,監聽端口 6000...\n");
// 5. 接受連接 (阻塞)
sockClient = accept(sockServer, (SOCKADDR*)&addrClient, &len);
if (sockClient == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(sockServer); WSACleanup(); return 1;
}
printf("客戶端 [%s:%d] 已連接\n",
inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));
// 6. 接收數據
int recvLen = recv(sockClient, recvBuf, sizeof(recvBuf)-1, 0);
if (recvLen > 0) {
recvBuf[recvLen] = '\0';
printf("收到: %s\n", recvBuf);
// 7. 回射發送
sprintf(sendBuf, "Echo: %s", recvBuf);
send(sockClient, sendBuf, (int)strlen(sendBuf), 0);
}
// 8. 清理
closesocket(sockClient);
closesocket(sockServer);
WSACleanup();
return 0;
}
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
SOCKET sockClient;
SOCKADDR_IN addrServer;
char sendBuf[100] = "Hello from Client!";
char recvBuf[100];
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) return 1;
sockClient = socket(AF_INET, SOCK_STREAM, 0);
if (sockClient == INVALID_SOCKET) { WSACleanup(); return 1; }
addrServer.sin_family = AF_INET;
addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 服務端IP
addrServer.sin_port = htons(6000);
if (connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)) == SOCKET_ERROR) {
printf("connect failed: %d\n", WSAGetLastError());
closesocket(sockClient); WSACleanup(); return 1;
}
printf("已連接到服務器\n");
send(sockClient, sendBuf, (int)strlen(sendBuf), 0);
int recvLen = recv(sockClient, recvBuf, sizeof(recvBuf)-1, 0);
if (recvLen > 0) {
recvBuf[recvLen] = '\0';
printf("服務器回應: %s\n", recvBuf);
}
closesocket(sockClient);
WSACleanup();
return 0;
}
htons/htonl (主機序→網絡序大端),ntohs/ntohl 逆向。IP地址、端口號必須轉換。accept/recv/send/connect均阻塞。高併發需用select/poll/epoll/IOCP或非阻塞+異步模型。recv返回長度不固定,應用層需自定義幀格式 (長度前綴/分隔符/定長) 邊界處理。closesocket與WSACleanup配對調用。WSAGetLastError()定位具體錯誤 (如WSAECONNREFUSED, WSAETIMEDOUT等)。Linux/Unix下頭文件換為<sys/socket.h>、<netinet/in.h>、<arpa/inet.h>、<unistd.h>;無需WSAStartup/WSACleanup;描述符類型為int;錯誤碼在errno;其餘邏輯一致。建議封裝跨平台Socket封裝層。