参考学习:C++:实现socket通信(TCP/IP)实例
1. 一对一
server.cpp
#include "pch.h"
#include <iostream>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
void initialization();
int main(){
int send_len = 0;
int recv_len = 0;
int len = 0;
char send_buf[100];
char recv_buf[100];
SOCKET s_server;
SOCKET s_accept;
SOCKADDR_IN server_addr;
SOCKADDR_IN accept_addr;
initialization();
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(5010);
s_server = socket(AF_INET, SOCK_STREAM, 0);
if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
std::cout << "套接字绑定失败!" << std::endl;
closesocket(s_server);
WSACleanup();
return 0;
}
else {
std::cout << "套接字绑定成功!" << std::endl;
}
if (listen(s_server, SOMAXCONN) < 0) {
std::cout << "设置监听状态失败!" << std::endl;
closesocket(s_server);
WSACleanup();
return 0;
}
else {
std::cout << "设置监听状态成功!" << std::endl;
}
std::cout << "服务端正在监听中......" << std::endl;
while (true) {
len = sizeof(SOCKADDR);
s_accept = accept(s_server, (SOCKADDR*)&accept_addr, &len);
if (s_accept == SOCKET_ERROR) {
std::cout << "连接失败!" << std::endl;
closesocket(s_server);
closesocket(s_accept);
WSACleanup();
return 0;
}
std::cout << "建立连接!准备接受数据。" << std::endl;
while (true) {
recv_len = recv(s_accept, recv_buf, 100, 0);
if (recv_len < 0) {
std::cout << "接受失败!" << std::endl;
break;
}
else {
std::cout << "客户端信息:" << recv_buf << std::endl;
}
if (strcmp(recv_buf, "bye") == 0) {
std::cout << "本次通信结束!" << std::endl;
std::cout << "服务端正在监听中......" << std::endl;
break;
}
std::cout << "请输入回复信息:";
std::cin >> send_buf;
send_len = send(s_accept, send_buf, 100, 0);
if (send_len < 0) {
std::cout << "发送失败!" << std::endl;
break;
}
}
}
closesocket(s_server);
closesocket(s_accept);
WSACleanup();
return 0;
}
void initialization() {
WORD w_req = MAKEWORD(2, 2);
WSADATA wsadata;
int err;
err = WSAStartup(w_req, &wsadata);
if (err != 0) {
std::cout << "初始化套接字库失败!" << std::endl;
}
else {
std::cout << "初始化套接字库正确!" << std::endl;
}
if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
std::cout << "套接字库版本号不符!" << std::endl;
WSACleanup();
}
else {
std::cout << "套接字库版本号正确!" << std::endl;
}
}
client.cpp
#include "pch.h"
#include <iostream>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
void initialization();
int main() {
int send_len = 0;
int recv_len = 0;
char send_buf[100];
char recv_buf[100];
SOCKET s_server;
SOCKADDR_IN server_addr;
initialization();
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(5010);
s_server = socket(AF_INET, SOCK_STREAM, 0);
if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
std::cout << "服务器连接失败!" << std::endl;
closesocket(s_server);
WSACleanup();
return 0;
}
else {
std::cout << "服务器连接成功!" << std::endl;
}
while (true) {
std::cout << "请输入发送信息:";
std::cin >> send_buf;
send_len = send(s_server, send_buf, 100, 0);
if (send_len < 0) {
std::cout << "发送失败!" << std::endl;
break;
}
if (strcmp(send_buf, "bye") == 0) {
std::cout << "本次通信结束!" << std::endl;
break;
}
recv_len = recv(s_server, recv_buf, 100, 0);
if (recv_len < 0) {
std::cout << "接受失败!" << std::endl;
break;
}
else {
std::cout << "服务器端信息:" << recv_buf << std::endl;
}
}
closesocket(s_server);
WSACleanup();
return 0;
}
void initialization() {
WORD w_req = MAKEWORD(2, 2);
WSADATA wsadata;
int err;
err = WSAStartup(w_req, &wsadata);
if (err != 0) {
std::cout << "初始化套接字库失败!" << std::endl;
}
else {
std::cout << "初始化套接字库正确!" << std::endl;
}
if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
std::cout << "套接字库版本号不符!" << std::endl;
WSACleanup();
}
else {
std::cout << "套接字库版本号正确!" << std::endl;
}
}
结果展示
2. 一对多
server.cpp
#include "pch.h"
#include <iostream>
#include <winsock.h>
#include <thread>
#include <mutex>
#pragma comment(lib,"ws2_32.lib")
void initialization();
std::mutex m;
void severThread(SOCKET s_accept) {
std::unique_lock<std::mutex> g(m, std::defer_lock);
bool isNamed = false;
char client_name[100];
int send_len = 0;
int recv_len = 0;
char send_buf[100];
char recv_buf[100];
while (true) {
recv_len = recv(s_accept, recv_buf, 100, 0);
if (recv_len < 0) {
std::cout << "接受失败!与客户端用户(" << client_name << " )断开连接。" << std::endl << std::endl;
std::cout << "服务端正在监听中......" << std::endl;
break;
}
else {
g.lock();
if (!isNamed) {
memcpy(client_name, recv_buf, strlen(recv_buf));
client_name[strlen(recv_buf)] = '\0';
std::cout << "客户端用户(" << client_name << " )已登录。" << std::endl;
}
else {
std::cout << "客户端用户(" << client_name << " ):" << recv_buf << std::endl;
}
}
if (!isNamed) {
isNamed = true;
}
else {
if (strcmp(recv_buf, "bye") == 0) {
std::cout << "本次通信结束!" << std::endl << std::endl;
std::cout << "服务端正在监听中......" << std::endl;
break;
}
std::cout << "请输入回复信息:";
std::cin >> send_buf;
send_len = send(s_accept, send_buf, 100, 0);
if (send_len < 0) {
std::cout << "发送失败!与客户端用户(" << client_name << " )断开连接。" << std::endl << std::endl;
std::cout << "服务端正在监听中......" << std::endl;
break;
}
}
g.unlock();
}
closesocket(s_accept);
}
int main(){
int send_len = 0;
int recv_len = 0;
int len = 0;
SOCKET s_server;
SOCKET s_accept;
SOCKADDR_IN server_addr;
SOCKADDR_IN accept_addr;
initialization();
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(5010);
s_server = socket(AF_INET, SOCK_STREAM, 0);
if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
std::cout << "套接字绑定失败!" << std::endl;
closesocket(s_server);
WSACleanup();
return 0;
}
else {
std::cout << "套接字绑定成功!" << std::endl;
}
if (listen(s_server, SOMAXCONN) < 0) {
std::cout << "设置监听状态失败!" << std::endl;
closesocket(s_server);
WSACleanup();
return 0;
}
else {
std::cout << "设置监听状态成功!" << std::endl;
}
std::cout << "服务端正在监听中......" << std::endl;
while (true) {
len = sizeof(SOCKADDR);
s_accept = accept(s_server, (SOCKADDR*)&accept_addr, &len);
if (s_accept == SOCKET_ERROR) {
std::cout << "连接失败!" << std::endl;
closesocket(s_server);
closesocket(s_accept);
WSACleanup();
return 0;
}
std::cout << "已与新客户端建立连接!等待新用户输入用户名......" << std::endl;
std::thread t(severThread, s_accept);
t.detach();
}
closesocket(s_server);
closesocket(s_accept);
WSACleanup();
return 0;
}
void initialization() {
WORD w_req = MAKEWORD(2, 2);
WSADATA wsadata;
int err;
err = WSAStartup(w_req, &wsadata);
if (err != 0) {
std::cout << "初始化套接字库失败!" << std::endl;
}
else {
std::cout << "初始化套接字库正确!" << std::endl;
}
if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
std::cout << "套接字库版本号不符!" << std::endl;
WSACleanup();
}
else {
std::cout << "套接字库版本号正确!" << std::endl;
}
}
client.cpp
#include "pch.h"
#include <iostream>
#include <winsock.h>
#include <thread>
#include <mutex>
#pragma comment(lib,"ws2_32.lib")
void initialization();
int main() {
int send_len = 0;
int recv_len = 0;
char send_buf[100];
char recv_buf[100];
SOCKET s_server;
SOCKADDR_IN server_addr;
bool isNamed = false;
initialization();
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(5010);
s_server = socket(AF_INET, SOCK_STREAM, 0);
if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
std::cout << "服务器连接失败!" << std::endl;
closesocket(s_server);
WSACleanup();
return 0;
}
else {
std::cout << "服务器连接成功!" << std::endl;
}
while (true) {
if (!isNamed) {
std::cout << "请输入用户名:";
std::cin >> send_buf;
send_len = send(s_server, send_buf, 100, 0);
if (send_len < 0) {
std::cout << "发送失败!" << std::endl;
break;
}
else {
std::cout << "用户名注册成功!" << std::endl;
isNamed = true;
}
}
std::cout << "请输入发送信息:";
std::cin >> send_buf;
send_len = send(s_server, send_buf, 100, 0);
if (send_len < 0) {
std::cout << "发送失败!" << std::endl;
break;
}
if (strcmp(send_buf, "bye") == 0) {
std::cout << "本次通信结束!" << std::endl;
break;
}
recv_len = recv(s_server, recv_buf, 100, 0);
if (recv_len < 0) {
std::cout << "接受失败!" << std::endl;
break;
}
else {
std::cout << "服务器端信息:" << recv_buf << std::endl;
}
}
closesocket(s_server);
WSACleanup();
return 0;
}
void initialization() {
WORD w_req = MAKEWORD(2, 2);
WSADATA wsadata;
int err;
err = WSAStartup(w_req, &wsadata);
if (err != 0) {
std::cout << "初始化套接字库失败!" << std::endl;
}
else {
std::cout << "初始化套接字库正确!" << std::endl;
}
if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
std::cout << "套接字库版本号不符!" << std::endl;
WSACleanup();
}
else {
std::cout << "套接字库版本号正确!" << std::endl;
}
}
结果展示