才疏学前,关于socket通信的问题,求指导
小弟不才,浅学socket。我是写一个cs模式,(server精灵挂起)server接收client的数字表达式字符串,然后进行计算后回发结果给client,
当初发现在client端按Ctrl+c后,发现server也同时断开,然后逛了一下论坛,才知道是sigpipe,用大神教的方法解决了。
然后自己再想想,能不能在client端发个结束标志?
代码如下
server端:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <memory.h>
#include <signal.h>
int exit_code = 0;
extern void* recv_thread(void*p);
void handle_pipe(int sig){}
int main()
{
pid_t pid1;
if(pid1=fork()==0)
{
setsid();
chdir("/";
close(0);close(1);close(2);
umask(0);
//1.创建sonket
int sockfd = socket(PF_INET,SOCK_STREAM,0);
if(sockfd == -1)perror("",exit(-1);
//2.准备地址
struct sockaddr_in addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(12345);
inet_aton("127.0.0.1",&addr.sin_addr);
//3.绑定
int res = bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
if(res == -1)perror("绑定失败",exit(-1);
printf("绑定成功!\n";
//4.监听
if( listen(sockfd,100)==-1)
perror("监听失败!",exit(-1);
printf("监听启动\n";
while(1)
{
//5.等待客户端连接 len必须赋值
struct sockaddr_in fromaddr;
socklen_t len = sizeof(fromaddr);
int fd = accept(sockfd,(struct sockaddr*)&fromaddr,&len);
if(fd == -1)
perror("accept失败";
else
printf("有客户端连接服务器\n";
struct sigaction action;
action.sa_handler = handle_pipe;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGPIPE,&action,NULL);
//6.通信
pthread_t pid;
pthread_create(&pid,0,recv_thread,&fd);
pthread_join(pid,0);
}
} //精灵
// close(sockfd);
}
/*******************************/
void* recv_thread(void*q)
{
int fds = *(int*)q;
while(1)
{
double sum =0;
char a = {0};
double shuzi = {0};
char fuhao = {0};
read(fds,a,sizeof(a));
printf("客户说:%s\n",a);
if(*a=='q'||*a=='Q') \
{
sum = 88; \
write(fds,&sum,; ---- >检查结束标志
break; /
} /
int flag = 0;
int i,j=0,k=0;
static int p;
//字符转整形部分
for(i=0; a!='\0'; i++)
{
if(a=='*'||a=='/'||a=='+'||a=='-'||a=='=')
{
fuhao = a;
k++;
a = '\n';
shuzi = atoi(a+p);
// printf("%d ",shuzi);
j++;
p = i;
continue;
}
}
//检查部分
for(flag=0; flag<j; flag++)
{
printf("%.2lf ",shuzi);
printf("%c ",fuhao);
}
printf("\n";
//乘除运算部分
int success;
// double* temp = (double*)malloc(sizeof(double)*100);
double temp = {0};
// double sum =0;
success = 0;
for(i=0; i<k-1;i++)
{
if(fuhao=='*')
{
int z = 0;
flag = 0;
for(z=j-1; z>i-1; z--)
{
temp = shuzi;
shuzi = 0;
flag++;
}
flag = flag - 1;
sum = temp*temp;
/*重构数字数组*/
shuzi = sum;
printf("%d %d %d\n",flag,j,i);
for(z=i+1; z<j-1; z++,flag--)
{ shuzi = temp;}
for(z=0; z<j-1; z++)
{ printf("%d ",shuzi);}
j--;
success = 1;
}
if(fuhao=='/')
{
int z = 0;
flag = 0;
for(z=j-1; z>i-1; z--)
{
temp = shuzi;
shuzi = 0;
flag++;
}
flag = flag - 1;
sum = temp/temp;
/*重构数字数组*/
shuzi = sum;
printf("%d %d %d\n",flag,j,i);
for(z=i+1; z<j-1; z++,flag--)
{ shuzi = temp;}
for(z=0; z<j-1; z++)
{ printf("%.2lf ",shuzi);}
j--;
success = 1;
}
/*重构符号数组*/
if(success == 1)
{
int f;
for(f=i; f<j; f++){
fuhao = fuhao;
printf("%c ",fuhao);
}
k--;
success = 0;
i = i - 1;
}
}
printf("\n%.2lf\n",sum);
write(fds,&sum,;
p = 0;
memset(a,0,100);
memset(shuzi,0,100);
memset(fuhao,0,100);
memset(temp,0,100);
}
close(fds);
return ((void*)exit_code);
}
/*************************************************************/
client端
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
int main()
{
//1.创建sonket
int sockfd = socket(PF_INET,SOCK_STREAM,0);
if(sockfd == -1)perror("",exit(-1);
//2.准备地址
struct sockaddr_in addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(12345);
inet_aton("127.0.0.1",&addr.sin_addr);
//3.连接
int res = connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));
if(res == -1)perror("connect失败"),exit(-1);
printf("连接成功!\n");
while(1)
{
char arg = {0};
printf("输入运算表达式:");
scanf("%s",arg);
printf("%s",arg); <------为啥没反应?
if(arg=='q') printf("退出!\n"),exit(0) ; <------为啥没反应?
//6.通信
double sum =0;
write(sockfd,arg,strlen(arg));
read(sockfd,&sum,;
printf("服务器运算结果说:%.2lf\n",sum);
}
printf("!!!!!!!!\n");
//7.关闭
close(sockfd);
}
按q后发现,server断开与client的通信,但是client不能反悔shell界面。server端使用了线程,是不是线程问题?还是内存问题?
求大神知道! 自己close自己的socket之后再写socket才会出SIGPIPE, 说实话这种错误永远也不应该发生,发生了就要反思自己的代码。 注册一个信号处理函数——SIGTERM(即CTRL-C)
在该信号函数中使用shutdown关闭写端,可以继续读 谢谢指点,其实ctrl-c的问题我已经解决,现在的问题是对离开标志‘q’
为什么客户端没响应,而服务端就有响应 回复 3# lxyscls_cu
谢谢指点,其实ctrl-c的问题我已经解决,现在的问题是对离开标志‘q’
为什么客户端没响应,而服务端就有响应
本帖最后由 lxyscls_cu 于 2012-11-02 12:48 编辑
{:3_189:} 奇怪 用楼主的代码 我怎么能退出到shell啊... 汗,可以用子进程来实现吧
页:
[1]