基於TCP的socket通信,實現加減乘除和文件寫入(方法二)

服務器端

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/wait.h>
#include<errno.h>
#include<unistd.h>
#include<signal.h>
#include<netdb.h>

void sig_handler(int signo)
{
	pid_t pid;
	int stat;
	pid=waitpid(-1,&stat,WNOHANG);
	while(pid>0){
	printf("child process terminated (PID:%ld)\n",(long)getpid());
	pid=waitpid(-1,&stat,WNOHANG);
	}
	return ;
}

typedef struct {
        char s[10];
        float a;
        float b;
        char m[1024];
        }Message;

int main(int argc,char *argv[])
{
	socklen_t clt_addr_len;
	int listen_fd;
	int com_fd;
	int ret;
	int result,a,b;
	int s[2];
	static char recv_buf[1024];
	int len;
	int port;
	pid_t pid;
	char *delim = " ";
	char *p;
	char *c;
	struct sockaddr_in clt_addr;
	struct sockaddr_in srv_addr;

	//服務器端運行時要給出端口信息,該端口爲監聽端口
	if(argc!=2){
	printf("Usage:%s port\n",argv[0]);
	return 1;
	}

	//獲得輸入的端口
	port=atoi(argv[1]);
	//設置信號處理函數,也可以使用sigaction函數
	if(signal(SIGCHLD,sig_handler)<0){
	perror("cannot set the signal");
	return 1;
	}

	//創建套接字用於服務器的監聽
	listen_fd=socket(PF_INET,SOCK_STREAM,0);
	if(listen_fd<0){
	perror("cannot create listening socket");
	return 1;
	}

	bzero(&srv_addr,sizeof(srv_addr));
	srv_addr.sin_family=AF_INET;
	srv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	srv_addr.sin_port=htons(port);

	ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
	if(ret==1)
	{
	perror("cannot bind server socket");
	close(listen_fd);
	return 1;
	}
	//監聽指定端口 ,連接一千個客戶端
	ret=listen(listen_fd,1000);
	if(ret==-1){
	perror("cannot listen the client connect request");
	return 1;
	}

	//對每個連接來的客戶端創建一個進程,單獨與其進行通信
	//首先調用read函數讀取客戶端發送來的信息
	//當輸入exit時程序退出
	while(1){
	len=sizeof(clt_addr);
	com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
	if(com_fd<0){
	if(errno==EINTR){
		continue;
	}else{
		perror("cannot accept client connect request");
		close(listen_fd);
		return 1;
	}
	}
	pid=fork();
	if(pid<0){
	perror("cannot create the child process");
	close(listen_fd);
	return 1;
	}else if(pid==0){
	Message mes;
	int n=sizeof(mes);
	while((len = read(com_fd,&mes,n))>0){
		if(strcmp(mes.s,"echo")==0){	
		printf("接收到客戶端的信息: %s %s\n",mes.s,mes.m);
		sprintf(recv_buf,"%s",mes.m);
		}
		else if(strcmp(mes.s,"add")==0){
		printf("接收到客戶端的信息:%s %f %f\n",mes.s,mes.a,mes.b);
		float result=mes.a+mes.b;
		sprintf(recv_buf,"%f",result);
		}
		else if(strcmp(mes.s,"sub")==0){
                printf("接收到客戶端的信息:%s %f %f\n",mes.s,mes.a,mes.b);
                float result=mes.a-mes.b;
                sprintf(recv_buf,"%f",result);
                }
		else if(strcmp(mes.s,"mul")==0){
                printf("接收到客戶端的信息:%s %f %f\n",mes.s,mes.a,mes.b);
                float result=mes.a*mes.b;
		sprintf(recv_buf,"%f",result);
                }
		else	if(strcmp(mes.s,"div")==0){
                printf("接收到客戶端的信息:%s %f %f\n",mes.s,mes.a,mes.b);
                if(mes.b==0){
		printf("除數不能爲零!\n");
		}else{
		float result=mes.a/mes.b;
		sprintf(recv_buf,"%f",result);
		}
                }
		else if(strcmp(mes.s,"exit")==0){
		close(com_fd);
        	return 0;
		}else
			printf("非法操作!\n");
	write(com_fd,recv_buf,strlen(recv_buf));
	memset(recv_buf,0,1024);
	}
	close(com_fd);
	return 0;
	}
	}
	return 0;
}


客戶端

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<netdb.h>
#include<unistd.h>

int main(int argc,char *argv[]){
	int connect_fd;
	int ret;	
	int port;
	int len;
	int result;
	static char snd_buf[1024];
	static struct sockaddr_in srv_addr;
	typedef struct {
	char s[10];
	float a;
	float b;
	char m[1024];
	}Message;
	//客戶端運行需要給出具體的鏈接地址和端口
	if(argc!=3){
		printf("Usage:%s server_ip_address port\n",argv[0]);
		return 1;
	}
	
	port=atoi(argv[2]);
	
	connect_fd=socket(PF_INET,SOCK_STREAM,0);
	if(connect_fd<0){
		perror("cannot create communication socket");
		return 1;
	}
	bzero(&srv_addr,sizeof(srv_addr));
	srv_addr.sin_family=AF_INET;
	srv_addr.sin_addr.s_addr=inet_addr(argv[1]);
	srv_addr.sin_port=htons(port);
	//連接指定的服務器
	ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
	if(ret==-1){
		perror("cannot connect to the server");
		close(connect_fd);
		return 1;
	}
	int size = 1024;
	
	//用戶輸入信息後,程序將輸入的信息通過套接字發送給服務器
	//然後調用read函數從服務器中讀取發送來的消息
	//當輸入exit時,程序退出
	while(1){
		Message mes;
		int n=sizeof(mes);
		printf("請輸入需要的操作:");
		scanf("%s",mes.s);
		if(strcmp(mes.s,"echo")==0)
			fgets(mes.m,1024,stdin);
		else 
			scanf("%f%f",&mes.a,&mes.b);	
		write(connect_fd,&mes,n);
		len = read(connect_fd,snd_buf,1024);
		if(len>0)
		printf("服務器返回:%s\n",snd_buf);
		memset(snd_buf,0,1024);
	}
	close(connect_fd);
	return 0;
		
}


程序運行:

#./server 5000

#./client 192.168.1.1245000 

IP寫你自己服務器的IP

你想讓服務器監聽哪個端口,後面就跟哪個端口



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章