服务端
//
// Tcp_server.cpp
// Cpp
//
// Created by JH on 2020/4/5.
// Copyright © 2020 JH. All rights reserved.
//
#include <stdio.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define PORT 8111
#define MESSAGE_LEN 1024
int main(int argc,char * argv[]){
int ret = -1;
int socket_fd ,accept_fd;
int on =1;
int backlog = 10;
pid_t pid;
char in_buff[MESSAGE_LEN] ={0};
struct sockaddr_in localaddr,remoteaddr;
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
exit(-1);
}
ret = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (ret == -1) {
std:: cout << "set option failed" << std::endl;
exit(-1);
}
localaddr.sin_family = AF_INET;
localaddr.sin_port = PORT;
localaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(localaddr.sin_zero), 8);
ret = bind(socket_fd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr));
if (ret == -1) {
std:: cout << "set bind failed" << std::endl;
exit(-1);
}
ret = listen(socket_fd, backlog);
if (ret == -1) {
std:: cout << "set listen failed" << std::endl;
exit(-1);
}
// if (daemon(0, 0) == -1) {
// std::cout <<"后台出错" << std::endl;
// exit(-1);
// }
//
ssize_t size;
for (; ; ) {
socklen_t addr_len = sizeof(struct sockaddr);
//接收客户端的socket
accept_fd = accept(socket_fd, (struct sockaddr *)& remoteaddr, &addr_len);
pid =fork();
if (pid == 0) { // 等于0表示子进程,缺点:资源被长期占用,分配子进程花费时间长
for (; ; ) {
memset(in_buff, 0, MESSAGE_LEN);
size = recv(accept_fd, (void *) in_buff, MESSAGE_LEN, 0);
if (size < 0) {
break;
}
std:: cout <<"recv : " <<in_buff << std::endl;
send(accept_fd, (void *)in_buff, MESSAGE_LEN, 0);
}
close(accept_fd);
}
}
// close(socket_fd);
return 0;
}
客户端代码
//
// Tcp_Client.cpp
// Cpp
//
// Created by JH on 2020/4/7.
// Copyright © 2020 JH. All rights reserved.
//
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8111
#define MESSAEG_LEN 1024
int main(int argc,char *argv[]){
int socket_fd;
int ret;
char sendbuf[MESSAEG_LEN] ={0};
char recvbuf[MESSAEG_LEN] ={0};
struct sockaddr_in serveraddr;
ssize_t status;
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
std::cout<< "failed to create socekt" << std::endl;
exit(-1);
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = PORT;
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
socklen_t size =sizeof(struct sockaddr);
ret = connect(socket_fd, (struct sockaddr*)&serveraddr, size);
if (ret < 0) {
std:: cout << "failed to connect server !" <<std::endl;
exit(-1);
}
while (1) {
//清空sendbuf
memset(sendbuf, 0, MESSAEG_LEN);
gets(sendbuf);
status = send(socket_fd, sendbuf, strlen(sendbuf), 0);
if (status < 0) {
std:: cout << "failed to send message !" <<std::endl;
exit(-1);
}
if (strcmp(sendbuf, "quit")==0) {
break;
}
status = recv(socket_fd, recvbuf, MESSAEG_LEN, 0);
recvbuf[status] = '\0';
std:: cout<< "recv:"<<recvbuf <<std::endl;
}
close(socket_fd);
return 0;
}
服务端输入命令
C++ -g -o tcp_server Tcp_server.cpp
./tcp_server
使用fork()可以接收多个客户端发送来的消息。
fork的缺点:资源被长期占用,分配子进程花费时间长