簡單的講下流程:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "WSOCK32.LIB")
#endif
// 應用程序 開始之前必須先 啟動這個,后面才能使用 winsock 的功能
WORD version_requested = MAKEWORD(2, 2);
WSADATA wsadata;
int err = WSAStartup(version_requested, &wsadata); // 啟動 winsock 服務
if (err != 0) {
printf("Startup failed\n");
return;
}
#endif
if (server_socket != INVALID_SOCKET) {
closesocket(server_socket); // 關掉 socket
}
WSACleanup(); // 終止 winsock 服務
// 創建一個 socket, 用來監聽客戶端的連接, TCP 的 socket
int server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket == INVALID_SOCKET) {
goto Failed;
}
printf("Starting bind socket at port %d ...\n", port);
// 配置信息
struct sockaddr_in addr;
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // IP
addr.sin_port = htons(port); // port
addr.sin_family = AF_INET; // protocol
// end
int ret = bind(server_socket, (const struct sockaddr*)&addr, sizeof(addr)); // 綁定 socket
if (ret != 0) {
printf("Bind %s:%d error\n", "127.0.0.1", port);
goto Failed;
}
printf("Bind %s:%d success\n", "127.0.0.1", port);
printf("Starting listener on %d ...\n", port);
ret = listen(server_socket, 128); // 開始監聽這個 socket , 限制隊列的最大連接數
if (ret != 0) {
printf("Listening on %d failed\n", port);
goto Failed;
}
printf("Listening on %d success\n", port);
fd_set server_fd_set; // 管理所有 socket 的集合
while (1) { // 使用 select 模型來等待處理 socket 事件
FD_ZERO(&server_fd_set); // 清空這個 socket 集合
FD_SET(server_socket, &server_fd_set); // 將監聽 socket 添加到集合里
printf("Waiting...\n");
int ret = select(0, &server_fd_set, NULL, NULL, NULL); // 等待監聽集合里所有的句柄
if (ret < 0) {
printf("Select error\n");
}
else if (ret == 0) { // 表示超時: 實現應用程序的定時器
continue;
}
printf("Wait for data\n");
// part1: 監聽端口進來的連接信息
if (FD_ISSET(server_socket, &server_fd_set)) { // 監聽端口有可讀數據
// 將端口監聽進來
struct sockaddr_in c_addr;
int len = sizeof(c_addr);
int client_socket = accept(server_socket, (struct sockaddr*)&c_addr, &len); // 創建和客戶端對應的 socket
if (client_socket != INVALID_SOCKET) {
printf("New client %s:%d comming\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
}
}
// 創建一個與服務器連接的 socket, TCP socket
int client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_socket == INVALID_SOCKET) {
return -1;
}
// 配置信息
struct sockaddr_in sockaddr;
sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
sockaddr.sin_port = htons(6000);
sockaddr.sin_family = AF_INET;
// end
int ret = connect(client_socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); // 連接 socket
if (ret != 0) {
printf("Connect error\n");
goto Failed;
}
printf("Connect success\n");
system("pause");
Failed :
if (client_socket != INVALID_SOCKET) {
closesocket(client_socket); // 關掉 socket
}
效果圖:
服務器:

客戶端:

到此結束咯!
方便他人,亦是方便自己!
