TCP/IP之多进程通信(TCP)

文章目录

server

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <stdbool.h>
#include <signal.h>
#include <sys/wait.h>

uint16_t sockConnect=-1;
uint8_t server_fd = -1;

void Call_handle(void);
void handle_SIGINT(int sig);
void handle_SIGCHLD(int sig);
int init(int server_fd, char* argv[]);
bool conmmunication(int server_fd);
void client_handle(struct sockaddr_in client_addr);

//#ifdef N
#define N 1
//#endif

int main (int argc,char *argv[])
{	
	Call_handle();
	bool flag = init(server_fd,argv);
	if(flag==0)
	{
		perror("init");
		close(server_fd);
		exit(EXIT_FAILURE);
	}
	return 0;
}
int init(int server_fd, char* argv[])
{	
	struct sockaddr_in server_addr;
	int on = 1;
	server_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(server_fd<0)
	{
		perror("socket");
		exit(EXIT_FAILURE);
	}
	/*地址快速重用*/
	if(setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))==-1)
	{
		perror("setsockopt");
		return 0;
	}
	memset(&server_addr, 0, sizeof(struct sockaddr_in));
	/* 设置服务器地址结构体的成员 */
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(atoi(argv[2]));//htons(8080)
	#if N==1 
		if ( inet_aton(argv[1], &server_addr.sin_addr)==0)
			{
				perror("inet_aton");
				return 0;
			}
	#else
			server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr(argv[1])
	#endif
	/*将套接字绑定到服务器地址上*/
	if(-1==bind( server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr) ))
	{
		perror("bind_faild");
		return 0;
	}
	/*按队列顺序监听套接字*/
	if( -1==listen(server_fd, 5) )
	{
		perror("listen");
		return 0;	
	}
	return conmmunication( server_fd);
}



bool conmmunication(int server_fd)
{
	pid_t pid;
	struct sockaddr_in client_addr;
	socklen_t len = sizeof(client_addr);
	while(1)
	{	
		sockConnect = accept(server_fd, (struct sockaddr *)&client_addr, &len);
		if(sockConnect<0)
		{
			perror("accept is failed");
			return 0;
		}
		uint8_t sendBuf[100]={0};
		printf("---------------client ip(%s) port(%d) to server---------------\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
		sprintf(sendBuf,"welcome client ip(%s) port(%d) to server!",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
		ssize_t check = send(sockConnect, sendBuf, strlen(sendBuf)+1, 0);//发送字符串给客户端

		if(check == -1)
		{
			perror("send");
			close(sockConnect);
			return 0;
		}
		if((pid=fork())==-1)
		{
			perror("fork");
			close(sockConnect);
			return 0 ;
		}
		else if(pid ==0){
			close(server_fd);
			client_handle(client_addr);
			exit(0);
		}
		else if(pid > 0)
		{
			close(sockConnect);
			//exit (EXIT_SUCCESS);
		}
	}
}

void client_handle(struct sockaddr_in client_addr)
{
	uint8_t recvbuf[BUFSIZ]={0};
	while(1)
		{	
			memset(recvbuf,0,BUFSIZ);
		#if N == 1
			ssize_t len = recv(sockConnect, recvbuf, sizeof(recvbuf), 0);
			if (len == -1) 
			{
				perror("recv");
				close(sockConnect);
				break;
			}
			else if(len == 0)
			{
				printf("---------------client ip(%s) port(%d) disconnected!---------------\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
				close(sockConnect);
				break;
			}
			printf("recv: %s", recvbuf);
			
			// send(sockConnect, buf, len1, 0);
			
		#else
				memset(buf,0,BUFSIZ);
				ssize_t bytes_read = read(sockConnect,buf,BUFSIZ);
				if(bytes_read==-1){
					fprintf(stderr,"read ERROR:%s\n",strerror(errno));
					exit(EXIT_FAILURE);
				}
				else{
					printf("recv:%s",buf);
				}
		#endif
		}
}

void Call_handle(void)
{
	struct sigaction act1;
	act1.sa_handler = handle_SIGINT;
	act1.sa_flags = 0;
	sigemptyset(&act1.sa_mask);
	sigaction(SIGINT, &act1, NULL);

	struct sigaction act2;
	act2.sa_handler = handle_SIGCHLD;
	act2.sa_flags = SA_RESTART;
	sigemptyset(&act2.sa_mask);
	sigaction(SIGCHLD, &act2, NULL);

}

void handle_SIGINT(int sig){
	if(sockConnect>0){
		close(sockConnect);
	}
	if(server_fd>0){
		close(server_fd);
	}
	exit(EXIT_SUCCESS);
}

void handle_SIGCHLD(int sig)
{
	if(sig == SIGCHLD)
	while(waitpid(-1,NULL,WNOHANG)>0);
	
}

client

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>


int sock_fd = -1;
void Call_handle(void);
void handle_SIGINT(int sig);
int main (int argc, char *argv[])
{
    if(argc!=3)
    {
        printf("Usage: %s <server_ip> <port>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    Call_handle();
    sock_fd=socket(AF_INET, SOCK_STREAM, 0);
    if(sock_fd<0)
    {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    
    struct sockaddr_in client_addr;
    memset(&client_addr, 0, sizeof(client_addr));
    client_addr.sin_family=AF_INET;
    client_addr.sin_port=htons(atoi(argv[2]));//htons(PORT);
    //client_addr.sin_addr.s_addr=inet_addr(SERVER_IP);
    if ( inet_aton(argv[1], &client_addr.sin_addr)==0)
		{
			perror("inet_aton");
			return -1;
		}
    if(connect(sock_fd, (struct sockaddr *)&client_addr, sizeof(client_addr))<0)
    {
        perror("connect");
        close(sock_fd);
        exit(EXIT_FAILURE);
    }
    
    printf("Connect to server successfully!\n");
    // char recvBuf[BUFSIZ]={0};
    // recv(sock_fd, recvBuf, sizeof(recvBuf), 0);
    // printf("receive server's msg:%s\n", recvBuf);

    char buf[BUFSIZ]={0};
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        printf("Please enter your message: ");
        fgets(buf, sizeof(buf), stdin);
        if(send(sock_fd, buf, strlen(buf), 0)<0)
        {
            perror("send");
            close(sock_fd);
            exit(EXIT_FAILURE);
        }

    }
           
   
}


void Call_handle(void)
{
	struct sigaction act;
	act.sa_handler = handle_SIGINT;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaction(SIGINT, &act, NULL);
}

void handle_SIGINT(int sig){
	
	if(sock_fd>0){
		close(sock_fd);
	}
	printf("SIGINT\n");
	exit(EXIT_SUCCESS);
}

Makefile

CC=gcc
CFLAGS=-Wall
all: multi_process_server multi_process_client

clean:
	rm multi_process_server multi_process_client
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值