本篇将讲解c++的socket实现
IDE
推荐大家使用 Microsoft Visual Studio,可以省去很多繁琐的设定
1.新建项目
server端
新建项目 server,并添加源文件 server.cpp
client端
新建项目 client,并添加源文件 client.cpp
2.加载socket库
server端 && client端
#include <iostream>
#include <thread> //多线程
#include <winsock.h> //socket头文件
#pragma comment (lib,"ws2_32.lib") //加载socket
using namespace std;
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
/*具体实现代码*/
WSACleanup();
return 0;
}
3.创建套接字(socket)
调用socket函数创建套接字
server端
SOCKET server;
SOCKET client;
server = socket(AF_INET, SOCK_STREAM, 0);
client端
SOCKET client;
client = socket(AF_INET, SOCK_STREAM, 0);
4.绑定端口与连接
server端
在server端调用函数bind绑定端口,listen设定同时最大连接数,accept接受client端的连接
int len;
SOCKADDR_IN server_addr;//使用结构体 SOCKADDR_IN 存储配置
SOCKADDR_IN client_addr;
memset(&server_addr, 0, sizeof(server_addr)); //清零
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //server端ip地址
server_addr.sin_port = htons(1234); //监听端口
bind(server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
listen(server, 10);
cout << "等待连接......" << endl;
len = sizeof(SOCKADDR);
client = accept(server, (SOCKADDR*)&client_addr, &len);
cout << "连接成功" << endl;
client端
在client端调用函数connect连接server端
SOCKADDR_IN client_addr;//使用结构体 SOCKADDR_IN 存储配置
memset(&client_addr, 0, sizeof(client_addr)); //清零
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //server端ip地址
client_addr.sin_port = htons(1234); //监听端口
connect(client, (SOCKADDR*)&client_addr, sizeof(SOCKADDR));
server端要先bind,listen和accept,client端才能connect
因此运行程序时先运行server,再运行client
5.使用函数send和recv进行通信
单次通信(server端发送,client端接收)
server端
char send_buf[100];//发送缓冲区
cin >> send_buf;
send(client, send_buf, 100, 0);
client端
char recv_buf[100];//接收缓冲区
recv(client, recv_buf, 100, 0);
cout << recv_buf;
多次通信(双方都能多次发送和接收)
server端 && client端
创建两个子线程分别用于发送和接收
void Send(SOCKET client, char send_buf[]);
void Recv(SOCKET client, char recv_buf[]);
char send_buf[100];//发送缓冲区
char recv_buf[100];//接收缓冲区
thread thread_send;
thread thread_recv;
thread_send = thread(Send, client, send_buf);
thread_recv = thread(Recv, client, recv_buf);
thread_send.join();
thread_recv.join();
void Send(SOCKET client, char send_buf[]) {
while(true) {
cin >> send_buf;
send(client, send_buf, 100, 0);
}
}
void Recv(SOCKET client, char recv_buf[]) {
while(true) {
recv(client, recv_buf, 100, 0);
cout << recv_buf << endl;
}
}
6.关闭套接字
server端
//关闭套接字
closesocket(server);
closesocket(client);
client端
//关闭套接字
closesocket(client);
完整代码
server.cpp
#include <iostream>
#include <thread> //多线程
#include <winsock.h> //socket头文件
#pragma comment (lib,"ws2_32.lib") //加载socket
using namespace std;
void Send(SOCKET client, char send_buf[]);
void Recv(SOCKET client, char recv_buf[]);
int main()
{
int len;
char send_buf[100];//发送缓冲区
char recv_buf[100];//接收缓冲区
thread thread_send;
thread thread_recv;
SOCKET server;
SOCKET client;
SOCKADDR_IN server_addr;//使用结构体 SOCKADDR_IN 存储配置
SOCKADDR_IN client_addr;
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
server = socket(AF_INET, SOCK_STREAM, 0);
memset(&server_addr, 0, sizeof(server_addr)); //清零
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //server端ip地址
server_addr.sin_port = htons(1234); //监听端口
bind(server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
listen(server, 10);
cout << "等待连接......" << endl;
len = sizeof(SOCKADDR);
client = accept(server, (SOCKADDR*)&client_addr, &len);
cout << "连接成功" << endl;
thread_send = thread(Send, client, send_buf);
thread_recv = thread(Recv, client, recv_buf);
thread_send.join();
thread_recv.join();
//关闭套接字
closesocket(server);
closesocket(client);
WSACleanup();
return 0;
}
void Send(SOCKET client, char send_buf[]) {
while (true) {
cin >> send_buf;
send(client, send_buf, 100, 0);
}
}
void Recv(SOCKET client, char recv_buf[]) {
while (true) {
recv(client, recv_buf, 100, 0);
cout << recv_buf << endl;
}
}
client.cpp
#include <iostream>
#include <thread> //多线程
#include <winsock.h> //socket头文件
#pragma comment (lib,"ws2_32.lib") //加载socket
using namespace std;
void Send(SOCKET client, char send_buf[]);
void Recv(SOCKET client, char recv_buf[]);
int main()
{
char send_buf[100];//发送缓冲区
char recv_buf[100];//接收缓冲区
thread thread_send;
thread thread_recv;
SOCKET client;
SOCKADDR_IN client_addr;//使用结构体 SOCKADDR_IN 存储配置
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
client = socket(AF_INET, SOCK_STREAM, 0);
memset(&client_addr, 0, sizeof(client_addr)); //清零
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //server端ip地址
client_addr.sin_port = htons(1234); //监听端口
connect(client, (SOCKADDR*)&client_addr, sizeof(SOCKADDR));
thread_send = thread(Send, client, send_buf);
thread_recv = thread(Recv, client, recv_buf);
thread_send.join();
thread_recv.join();
//关闭套接字
closesocket(client);
WSACleanup();
return 0;
}
void Send(SOCKET client, char send_buf[]) {
while (true) {
cin >> send_buf;
send(client, send_buf, 100, 0);
}
}
void Recv(SOCKET client, char recv_buf[]) {
while (true) {
recv(client, recv_buf, 100, 0);
cout << recv_buf << endl;
}
}
本篇博客介绍了在Windows环境下使用C++进行TCP/IP Socket通信的详细步骤,包括在Visual Studio中新建项目、加载socket库、创建套接字、绑定端口与连接、通过send和recv进行通信,以及关闭套接字。博客提供了server端和client端的代码示例,指导读者实现两端的交互通信。
823





