TCP网络通信:服务器与客户端计算实现 (tcp服务器和客户端计算)
TCP(Tranission Control Protocol,传输控制协议)是互联网协议簇中的一种协议,它是一种可靠的、面向连接的、基于字节流的传输层协议。在网络通信中,TCP协议的应用十分广泛,既可以用于服务器与客户端之间的通信,也可以用于不同计算机之间的数据传输。
本文将以服务器与客户端之间的通信为例,介绍TCP网络通信的实现方法。
1. 服务器端实现
服务器端是指提供服务的计算机,它接收客户端的请求,并根据请求进行相应的处理,最后将结果返回给客户端。服务器端通常需要同时处理多个客户端的请求,因此需要具备高效的处理能力。
1.1 建立连接
在TCP通信中,服务器端需要先创建一个监听套接字,并指定端口号。客户端会通过该端口号与服务器端建立连接。服务器端可以通过以下代码实现:
“`c++
#include
#include
#pragma comment(lib,”ws2_32.lib”)
using namespace std;
int mn()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
cout
return -1;
}
int server_socket;
if ((server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
cout
return -1;
}
sockaddr_in server_addr;
ZeroMemory(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9000);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server_socket, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
cout
closesocket(server_socket);
return -1;
}
if (listen(server_socket, SOMAXCONN) == SOCKET_ERROR) {
cout
return -1;
}
cout
return 0;
}
“`
在上述代码中,首先调用WSAStartup函数初始化Winsock库,然后通过socket函数创建一个新的套接字。AF_INET表示该套接字采用IPv4协议族,SOCK_STREAM表示该套接字采用面向流的TCP协议,IPPROTO_TCP表示采用TCP协议。然后设置服务器的地址和端口号,并通过bind函数将这个套接字绑定到指定的地址和端口。
最后调用listen函数将套接字转换成监听套接字,使该套接字可以接受来自客户端的连接请求。
1.2 接受请求
接下来,服务器端需要接受来自客户端的连接请求,并在建立连接后处理客户端发送的数据。服务器端可以通过以下代码实现:
“`c++
SOCKET client_socket;
sockaddr_in client_addr;
int addrLen = sizeof(sockaddr_in);
while (true) {
if ((client_socket = accept(server_socket, (SOCKADDR*)&client_addr, &addrLen)) == INVALID_SOCKET) {
cout
continue;
}
cout
char buffer[1024];
int bytesRecv;
while (true) {
bytesRecv = recv(client_socket, buffer, 1024, 0);
if (bytesRecv == SOCKET_ERROR) {
cout
closesocket(client_socket);
continue;
}
if (bytesRecv == 0) {
cout
closesocket(client_socket);
break;
}
cout
//TODO:处理数据
}
}
“`
在上述代码中,使用accept函数等待客户端的连接请求,并在成功连接后输出客户端的IP地址和端口号。然后使用recv函数接收客户端发送的数据,如果接收失败则关闭客户端套接字并重新等待连接。如果客户端关闭连接,则关闭客户端套接字并退出循环。
服务器端可以在TODO处添加数据处理部分的代码,根据客户端的请求进行相应的处理,并使用send函数将处理结果返回给客户端。
2. 客户端实现
客户端是指通过网络与服务器端进行通信的计算机。客户端需要与服务器端建立连接,并发送请求以进行相应的操作。
2.1 建立连接
客户端需要根据服务器端的地址和端口号建立连接。客户端可以通过以下代码实现:
“`c++
#include
#include
#pragma comment(lib,”ws2_32.lib”)
using namespace std;
int mn()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
cout
return -1;
}
int client_socket;
if ((client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
cout
return -1;
}
sockaddr_in server_addr;
ZeroMemory(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9000);
server_addr.sin_addr.s_addr = inet_addr(“127.0.0.1”);
if (connect(client_socket, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
cout
closesocket(client_socket);
return -1;
}
cout
return 0;
}
“`
在上述代码中,首先调用WSAStartup函数初始化Winsock库,然后通过socket函数创建一个新的套接字。接着设置服务器的地址和端口号,并通过connect函数尝试连接到指定的地址和端口。
如果连接失败,则输出错误信息并关闭客户端套接字;否则输出连接成功信息。
2.2 发送请求
客户端连接成功后,需要发送请求给服务器并等待服务器的响应。客户端可以通过以下代码实现:
“`c++
char buffer[1024];
while (true) {
cin >> buffer;
if (strcmp(buffer, “quit”) == 0) {
send(client_socket, buffer, strlen(buffer) + 1, 0);
break;
}
send(client_socket, buffer, strlen(buffer) + 1, 0);
int bytesRecv = recv(client_socket, buffer, 1024, 0);
if (bytesRecv == SOCKET_ERROR) {
cout
break;
}
if (bytesRecv == 0) {
cout
break;
}
cout
}
closesocket(client_socket);
WSACleanup();
return 0;
“`
在上述代码中,使用send函数将客户端发送的数据发送到服务器,并使用recv函数接收服务器响应的数据。如果接收失败,则输出错误信息并退出循环。如果接收到的数据长度为0,则说明服务器已经关闭连接。
客户端可以使用quit命令退出连接。
3.