服務器端
#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
你想讓服務器監聽哪個端口,後面就跟哪個端口