TCP 多进程并发服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <arpa/inet.h>
int sig_f = 0;
void FuncSigInt(int sig);
int start_echo_server(int argc, char *argv[]);
void init_signal_handle(void);
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Please use: %s <IP listen_address> <server_listen_port> <server_vcd>\n", argv[0]);
return 1;
}
return start_echo_server(argc, argv);
}
void FuncSigInt(int sig) {
printf("[srv] SIGINT is coming!\n");
sig_f = 1;
}
void init_signal_handle(void){
struct sigaction sa;
sa.sa_flags = 0;
sa.sa_handler = FuncSigInt;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT,&sa,NULL);
}
int start_echo_server(int argc, char *argv[]){
const char *server_listen_fd = argv[1];
int server_listen_port = atoi(argv[2]);
const char *server_vcd = argv[3];
init_signal_handle();
int server_fd, client_socket;
struct sockaddr_in listen_address;
int addrlen = sizeof(listen_address);
// 创建套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
listen_address.sin_family = AF_INET;
listen_address.sin_addr.s_addr = inet_addr(server_listen_fd);
listen_address.sin_port = htons(server_listen_port);
// 绑定套接字到指定端口
if (bind(server_fd, (struct sockaddr *)&listen_address, sizeof(listen_address)) < 0) {
perror("bind failed");
return -1;
}
// 监听端口,等待连接
if (listen(server_fd, 3) < 0) {
perror("listen failed");
return -1;
}
printf("[srv] server[%s:%d][%s] is initializing!\n",server_listen_fd,server_listen_port,server_vcd);
while (!sig_f) {
if ((client_socket = accept(server_fd, (struct sockaddr *)&listen_address, (socklen_t *)&addrlen)) < 0) {
if(errno == EINTR){
continue;
}else{
return -1;
}
}
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(listen_address.sin_addr), client_ip, INET_ADDRSTRLEN);
printf("[srv] client[%s:%d] is accepted!\n",client_ip,ntohs(listen_address.sin_port));
char buffer[128];
ssize_t num_bytes;
while (1) {
memset(buffer, 0, sizeof(buffer));
if ((num_bytes = read(client_socket, buffer, sizeof(buffer) - 1))<= 0) {
break;
}
buffer[num_bytes] = '\0';
printf("[ECH_RQT]%s", buffer);
char reply_buffer[136];
snprintf(reply_buffer, sizeof(reply_buffer), "(%s)%s", server_vcd, buffer);
write(client_socket, reply_buffer, strlen(reply_buffer));
}
printf("[srv] client[%s:%d] is closed!\n",client_ip,ntohs(listen_address.sin_port));
close(client_socket);
}
if (server_fd != -1) {
close(server_fd);
}
return 0;
}
TCP单进程客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int start_client(int argc, char *argv[]); int main(int argc, char *argv[]) { if (argc != 3) { printf("请按正确参数使用: %s <ip_address> <port>\n", argv[0]); return 1; } return start_client(argc, argv); } int start_client(int argc, char *argv[]){ char* ip_address = argv[1]; int port = atoi(argv[2]); struct sockaddr_in server_address; int sockfd; // Create a socket sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); return 1; } // Set server address memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_port = htons(port); if (inet_pton(AF_INET, ip_address, &(server_address.sin_addr)) <= 0) { perror("inet_pton"); return 1; } // Connect to the server if (connect(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) { perror("connect"); return 1; } printf("[cli] server[%s:%d] is connected!\n", ip_address, port); char input_buffer[138]; ssize_t num_bytes; while (1) { memset(input_buffer, 0, sizeof(input_buffer)); if (fgets(input_buffer, sizeof(input_buffer), stdin) == NULL) { break; } printf("[ECH_RQT]%s", input_buffer); if (strncmp(input_buffer, "EXIT\n",5) == 0) { break; } write(sockfd, input_buffer, strlen(input_buffer)); char buffer[138]; ssize_t num_bytes; memset(buffer, 0, sizeof(buffer)); num_bytes = read(sockfd, buffer, sizeof(buffer) - 1); if (num_bytes <= 0) { break; } buffer[num_bytes] = '\0'; printf("[ECH_REP]%s", buffer); } close(sockfd); printf("[cli] connfd is closed!"); printf("[cli] clinet is to return!"); return 0; }