下面是针对“vc++实现的tcp socket客户端和服务端示例”的详细攻略:
一、什么是TCP Socket?
TCP(Transmission Control Protocol)是“传输控制协议”的缩写。它是一种基于连接的、可靠的、面向字节流的传输层协议,主要用于Internet上的数据传输。
Socket是指“套接字”,是一个软件API(Applications Programming Interface),是内核提供的通信机制,并且也是实现网络通信的一个标准。
二、实现TCP Socket客户端和服务端的步骤及对应代码
下面我们将分别介绍实现TCP Socket客户端和服务端的步骤及对应代码。
1. 实现TCP Socket客户端流程
- 创建Socket
首先,我们需要在客户端中创建一个Socket,代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsadata;
SOCKET sockClient;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
return -1;
}
sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockClient < 0)
{
return -1;
}
return 0;
}
在这段代码中,我们使用了WinSock2库中的socket函数来创建Socket。由于TCP是一种面向连接的协议,因此我们在创建Socket时需要指定协议类型(IPPROTO_TCP)和Socket类型(SOCK_STREAM)。
- 建立连接
建立连接的过程需要使用到connect函数。connect函数接收服务端地址,用于与服务端建立连接。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
{
return -1;
}
...
}
在这段代码中,我们首先定义了服务端的地址(包括端口号和IP地址),然后使用connect函数对Socket和服务端进行连接。
- 发送和接收数据
连接建立成功后,我们可以使用send函数来发送数据,使用recv函数来接收数据。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
char buf[] = "Hello World!";
send(sockClient, buf, strlen(buf), 0);
char recvBuf[100];
int len = recv(sockClient, recvBuf, 100, 0);
...
return 0;
}
在这段代码中,我们使用send函数发送了一个字符串(Hello World!),然后使用recv函数接收服务端返回的数据。可以看到,send和recv函数分别需要传入Socket、发送/接收的数据和数据长度等参数。
- 关闭Socket
最后,在完成客户端的所有操作后,我们需要使用closesocket函数来关闭Socket。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
closesocket(sockClient);
WSACleanup();
return 0;
}
2. 实现TCP Socket服务端流程
- 创建Socket
与客户端类似,我们首先需要在服务端中创建一个Socket,代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsadata;
SOCKET sockSrv;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
return -1;
}
sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockSrv < 0)
{
return -1;
}
return 0;
}
在这段代码中,我们同样使用了socket函数来创建Socket。
- 绑定地址和端口号
接下来,我们需要绑定本地地址和端口号。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
addrSrv.sin_addr.s_addr = INADDR_ANY;
if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
{
return -1;
}
...
}
在这段代码中,我们定义了本地地址(包括端口号和IP地址),并使用bind函数将Socket和地址进行绑定。
- 监听连接请求
绑定完成后,我们需要使用listen函数监听连接请求。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
if (listen(sockSrv, 10) < 0)
{
return -1;
}
...
}
在这段代码中,我们使用了listen函数来监听连接请求,参数10表示最大连接数。
- 接受连接请求
监听完成后,我们通过accept函数接收连接请求。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
...
}
在这段代码中,我们先定义了addrClient来存储客户端地址,然后使用accept函数接受连接请求,返回一个与客户端通信的Socket。
- 接收和发送数据
连接成功后,我们可以使用recv函数来接收客户端发送的数据,使用send函数来向客户端发送数据。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
char recvBuf[100];
int len = recv(sockConn, recvBuf, 100, 0);
char buf[] = "Hello Client!";
send(sockConn, buf, strlen(buf), 0);
...
}
在这段代码中,我们使用recv函数接收客户端发送的数据,然后使用send函数发送一段字符串给客户端。
- 关闭Socket
最后,在完成服务端的所有操作后,我们需要使用closesocket函数来关闭所有的Socket。代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
...
closesocket(sockSrv);
closesocket(sockConn);
WSACleanup();
return 0;
}
三、示例说明
以上是实现TCP Socket客户端和服务端的详细步骤,下面我将通过两个示例代码来展示具体实现方法。
示例一:通过TCP Socket实现简单的聊天室
在这个示例中,我们通过TCP Socket实现一个简单的聊天室。代码如下:
//Server
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#include <iostream>
using namespace std;
int main()
{
WSADATA wsadata;
SOCKET sockSrv, sockConn;
SOCKADDR_IN addrSrv, addrClient;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
return -1;
}
sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockSrv < 0)
{
return -1;
}
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
addrSrv.sin_addr.s_addr = INADDR_ANY;
if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
{
return -1;
}
if (listen(sockSrv, 10) < 0)
{
return -1;
}
int len = sizeof(SOCKADDR);
cout << "Server is listening..." << endl;
sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
cout << "A client connected!" << endl;
while (1)
{
char recvBuf[100];
int len = recv(sockConn, recvBuf, 100, 0);
if (len <= 0)
{
break;
}
recvBuf[len] = '\0';
cout << "Client: " << recvBuf << endl;
char buf[100];
cin >> buf;
send(sockConn, buf, strlen(buf), 0);
}
closesocket(sockSrv);
closesocket(sockConn);
WSACleanup();
return 0;
}
//Client
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#include <iostream>
using namespace std;
int main()
{
WSADATA wsadata;
SOCKET sockClient;
SOCKADDR_IN addrSrv;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
return -1;
}
sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockClient < 0)
{
return -1;
}
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
{
return -1;
}
cout << "Connected to server!" << endl;
while (1)
{
char buf[100];
cin >> buf;
send(sockClient, buf, strlen(buf), 0);
char recvBuf[100];
int len = recv(sockClient, recvBuf, 100, 0);
recvBuf[len] = '\0';
cout << "Server: " << recvBuf << endl;
}
closesocket(sockClient);
WSACleanup();
return 0;
}
在这个聊天室示例中,我们首先编写了一个服务端程序,用于监听连接请求。在客户端连接成功后,服务端会开始运行一个循环,等待客户端发送消息。当服务端接收到消息时,它会输出客户端发送的消息,并等待输入下一条消息发送给客户端。
客户端程序会首先连接到服务端,然后进入一个循环,等待用户输入消息。当用户输入一条消息时,客户端会将它发送给服务端,并等待服务端发送消息。客户端接收到服务端的消息后,会将该消息输出到屏幕上。
示例二:通过TCP Socket进行文件传输
在这个示例中,我们将使用TCP Socket实现简单的文件传输。将一个本地文件传输到远程机器上。该示例将演示文件的发送和接收过程。
服务端代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsadata;
SOCKET sockSrv, sockConn;
SOCKADDR_IN addrSrv;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
return -1;
}
sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockSrv < 0)
{
return -1;
}
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
addrSrv.sin_addr.s_addr = INADDR_ANY;
if (bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
{
return -1;
}
if (listen(sockSrv, 10) < 0)
{
return -1;
}
int len = sizeof(SOCKADDR);
sockConn = accept(sockSrv, NULL, NULL);
FILE* file = fopen("test.txt", "rb");
char buf[1024];
while (1)
{
int len = fread(buf, 1, 1024, file);
if (len <= 0)
{
break;
}
send(sockConn, buf, len, 0);
}
fclose(file);
closesocket(sockSrv);
closesocket(sockConn);
WSACleanup();
return 0;
}
客户端代码如下:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsadata;
SOCKET sockClient;
SOCKADDR_IN addrSrv;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
{
return -1;
}
sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockClient < 0)
{
return -1;
}
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) < 0)
{
return -1;
}
FILE* file = fopen("test_recv.txt", "wb");
char buf[1024];
while (1)
{
int len = recv(sockClient, buf, 1024, 0);
if (len <= 0)
{
break;
}
fwrite(buf, 1, len, file);
}
fclose(file);
closesocket(sockClient);
WSACleanup();
return 0;
}
本示例中,服务端首先通过文件流打开一个名为“test.txt”的本地文件,并每次读取1024字节的数据发送给客户端。客户端在接收到数据后,将接收到的数据写入到一个名为“test_recv.txt”的本地文件中。在完成数据传输后,服务端和客户端都会关闭连接和socket。
以上就是通过VC++实现TCP Socket客户端和服务端所需要遵循的流程及代码示例说明,希望对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vc++实现的tcp socket客户端和服务端示例 - Python技术站