一、server 端
1)创建socket,指定协议版本(v4,v6)、协议类型(udp、tcp),获得server fd。
2)bind本地地址
(1)通过server fd进行操作
(2)创建并设置sockaddr_in对象,设置对端的地址和端口信息:
server端,不指定具体的client地址,设置为INADDR_ANY
(3)指定监听端口
3)在server fd上启动监听。
4)接收client连接请求
(1)使用循环持续监听client请求
(2)收到client请求后,在server fd上调用accept获得client fd,client sockaddr_in对象
5)使用client fd进行收发数据
二、client 端
1)创建socket,指定协议版本和协议类型,获得server fd。
2)connect()连接服务器
(1)通过上面创建的server fd进行操作
(2)创建并设置sockaddr_in对象,设置对端的地址和端口信息:
client端,需要指定server的ip:port
(3)bind和connect入参相同,server fd, addr, addr_length
accept()函数参数类似,后两个参数为出参
3)完成连接后,通过server fd和服务器收发数据
cpp
#include <iostream>
#include <thread>
#include <netinet/in.h>
#include <cstring>
#include <arpa/inet.h>
#include <cassert>
using namespace std;
#define max_line 80
#define port 21339
void server_func() {
cout << "server begin\n";
struct sockaddr_in addr;
// 1. create udp socket and get the server fd
int server_fd = socket(PF_INET, SOCK_STREAM, 0);
assert(server_fd != -1);
bzero(&addr, sizeof(addr));
addr.sin_family = PF_INET; // v4
addr.sin_addr.s_addr = htonl(INADDR_ANY); // listen on any local address
addr.sin_port = htons(port);
// 2. bind local address with server fd
bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));
// 3. start listening on server fd
int ret = listen(server_fd, 10);
assert(ret != -1);
cout << "server: start listening\n";
struct sockaddr_in client_addr;
socklen_t len = 0;
char buf[max_line];
char addr_str[INET_ADDRSTRLEN];
// 4. loop and accept client's requests
int count = 1;
while(true) {
cout << "server: begin loop: " << count++ << endl;
bzero(&client_addr, sizeof(client_addr));
// 4.1 accept a client's request and get the client fd for interaction
// listen on server fd and get a client fd through the server fd
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &len);
assert(client_fd != -1);
inet_ntop(PF_INET, &client_addr.sin_addr, addr_str, sizeof(addr_str));
printf("server: accept client -> [%s:%d]\n", addr_str, client_addr.sin_port);
// 4.2 use the client fd to receive and send data
// int n = read(client_fd, buf, max_line);
int n = recv(client_fd, buf, max_line, 0);
for (int i=0; i<n; i++) {
buf[i] = toupper(buf[i]);
}
write(client_fd, buf, n);
close(client_fd);
cout << "server: end a loop.\n";
}
}
void client_func() {
cout << "client begin\n";
const char* msg = "hello";
char buf[max_line] = {0};
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
// inet_pton(PF_INET, "127.0.0.1", &server_addr.sin_addr);
server_addr.sin_family = PF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(port);
// 1. create a socket
int server_fd = socket(PF_INET, SOCK_STREAM, 0);
assert(server_fd != -1);
// 2. connect the socket and get the server fd
int ret = connect(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
cout << "client: failed to connect server, since: " << strerror(errno) << endl;
assert(ret != -1);
int len = strlen(msg);
// 3. send and receive data through the server fd
// write(server_fd, msg, len);
send(server_fd, msg, len, 0);
read(server_fd, buf, len);
cout << "read: " << buf << endl;
cout << "client end\n";
return;
}
int main() {
jthread server(server_func);
jthread client(client_func);
std::cout << "Hello, World!" << std::endl;
return 0;
}