socket 编写客户端与服务端代码
客户端代码
/**
* 客户端代码,每次将写入服务端的数据再读回来,利用 read 以及 write 函数完成 socket 读写
*/
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(int argc, char **argv) {
int sock;
char message[1024];
int str_len;
struct sockaddr_in server_addr;
if(argc != 3) {
std::cerr << "Usage:" << argv[0] << std::endl;
exit(1);
}
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) {
std::cerr << "socket error" << std::endl;
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
std::cerr << "Error connecting" << std::endl;
exit(1);
}
std::cout << "connecting********************************" << std::endl;
while(1) {
std::cout << "input message(Q to quit) :" << std::endl;
std::string buff;
std::cin >> buff;
if(buff == "Q" || buff == "q") {
break;
}
str_len = write(sock, buff.c_str(), buff.size());
int recv_len = 0;
int recv_cnt;
/**
* 读取数据不应该一次性读出,因为TCP连接是字节流传输,很有可能没有读到边界,所以应该设置为循环读取,保证读取到的数据跟写入的数据保持一致
*/
while (recv_len < str_len) {
recv_cnt = read(sock, message, 1024);
if(recv_cnt == -1) {
std::cout << "read error" << std::endl;
exit(1);
}
recv_len += recv_cnt;
}
message[recv_len] = '\0';
// str_len = read(sock, message, 1024);
// message[str_len] = '\0';
std::cout << message << std::endl;
}
close(sock);
return 0;
}
服务端代码
/**
* 最多完成五次客户端到服务端的连接,服务端调用顺序为 :
* 1. 创建 socket
* 2. 命名 socket
* 3. 监听 socket
* 4. 接受 socket // 接受 socket 后会创建一个新 socket 通信
* 5. 读写 socket
*/
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc, char **argv) {
int server_socket, client_socket;
char message[1024];
int str_len, i;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_sz;
if(argc != 2) {
std::cerr << "Usage: " << argv[0] << std::endl;
exit(1);
}
server_socket = socket(PF_INET, SOCK_STREAM, 0);
if(server_socket < 0) {
std::cerr << "socket error" << std::endl;
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
if(bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
std::cerr << "bind error" << std::endl;
exit(1);
}
if(listen(server_socket, 5) == -1) {
std::cerr << "listen error" << std::endl;
exit(1);
}
client_addr_sz = sizeof(client_addr);
for (int i = 0; i < 5; i++) {
client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &client_addr_sz);
if(client_socket == -1) {
std::cerr << "accept error" << std::endl;
exit(1);
}
else {
std::cout << "connected client" << i + 1 << std::endl;
}
while((str_len = read(client_socket, message, 1024)) != 0) {
write(client_socket, message, str_len);
}
close(client_socket);
}
close(server_socket);
return 0;
}