本位代码实现客户端输入相应需要计算的表达式,服务器做简单计算,并将结果返回。
头文件:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define INIT_THREAD_NUM 5
#define MAXLINE 1024
#define err_quit(m) \
do{ \
perror(m); \
exit(1); \
}while(0)
typedef enum{IDLE, BUSY}WORK_STATE;
typedef enum{ADD, SUB, MUL, DIV, MOD}OPER_ENUM;
typedef struct {
int op1;
int op2;
OPER_ENUM oper;
}oper_struct;
服务器代码:
#include "../utili.h"
void math_operation(oper_struct *ptr, int *res);
static void *th_fn(void *arg);
int main()
{
int listenfd;
struct sockaddr_in servaddr;
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_quit("socket err.\n");
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6666);
servaddr.sin_addr.s_addr = INADDR_ANY;
int on = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
err_quit("bind err.\n");
if(listen(listenfd, SOMAXCONN) < 0)
err_quit("listen err.\n");
int *ptr_connfd;
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);
pthread_t tid;
for(; ;){
ptr_connfd = (int *)malloc(sizeof(int));
if( (*ptr_connfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len)) < 0)
err_quit("accept err.\n");
else
printf("client: IP:%s PORT:%d connect.\n", inet_ntoa(clientaddr.sin_addr),
ntohs(clientaddr.sin_port));
if(pthread_create(&tid, NULL, th_fn, ptr_connfd) != 0)
err_quit("create pthread err.\n");
}
return 0;
}
void math_operation(oper_struct *ptr, int *res)
{
switch(ptr->oper){
case ADD:
*res = ptr->op1 + ptr->op2;
break;
case SUB:
*res = ptr->op1 - ptr->op2;
break;
case MUL:
*res = ptr->op1 * ptr->op2;
break;
case DIV:
*res = ptr->op1 / ptr->op2;
break;
case MOD:
*res = ptr->op1 % ptr->op2;
break;
default:
break;
}
}
static void *th_fn(void *arg)
{
pthread_detach(pthread_self());
int connfd = *(int *)arg;
free(arg);
int res;
oper_struct ops;
for(; ;){
recv(connfd, &ops, sizeof(ops), 0);
math_operation(&ops, &res);
printf("the result is:%d\n", res);
send(connfd, &res, sizeof(res), 0);
}
close(connfd);
return (void *)0;
}
客户端代码:
#include "../utili.h"
void input_opernum(oper_struct *pointer);
int main()
{
int sockfd;
struct sockaddr_in servaddr;
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_quit("socket err.\n");
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6666);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
err_quit("connect err.\n");
oper_struct ops;
char *symbol;
char recvbuff[MAXLINE];
for( ; ;){
printf("please input operator symbol:>\n");
scanf("%s", symbol);
if(strncmp(symbol, "add", 3) == 0){
ops.oper = ADD;
input_opernum(&ops);
}
else if(strncmp(symbol, "sub", 3) == 0){
ops.oper = SUB;
input_opernum(&ops);
}
else if(strncmp(symbol, "mul", 3) == 0){
ops.oper = MUL;
input_opernum(&ops);
}
else if(strncmp(symbol, "div", 3) == 0){
ops.oper = DIV;
input_opernum(&ops);
}
else if(strncmp(symbol, "mod", 3) == 0){
ops.oper = MOD;
input_opernum(&ops);
}
else{
printf("invilid input.\n");
continue;
}
send(sockfd, &ops, sizeof(ops), 0);
recv(sockfd, recvbuff, sizeof(int), 0);
printf("the answer is:>%d\n", *(int*)recvbuff);
}
close(sockfd);
return 0;
}
void input_opernum(oper_struct *pointer)
{
printf("please input operation num:>\n");
scanf("%d %d", &(pointer->op1), &(pointer->op2));
}