免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1846 | 回复: 7
打印 上一主题 下一主题

[学习] 才疏学前,关于socket通信的问题,求指导 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-01 14:58 |只看该作者 |倒序浏览
小弟不才,浅学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[100] = {0};
        double shuzi[100] = {0};
        char fuhao[100] = {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[i]!='\0'; i++)
        {
                if(a[i]=='*'||a[i]=='/'||a[i]=='+'||a[i]=='-'||a[i]=='=')
                {
                        fuhao[k] = a[i];
                        k++;
                        a[i] = '\n';
                        shuzi[j] = atoi(a+p);
//                        printf("%d ",shuzi[j]);
                        j++;
                        p = i;
                        continue;
                }
        }
//检查部分
        for(flag=0; flag<j; flag++)
        {
                printf("%.2lf ",shuzi[flag]);
                printf("%c ",fuhao[flag]);
        }                                                   
        printf("\n";  
//乘除运算部分
        int success;        
//        double* temp = (double*)malloc(sizeof(double)*100);
        double temp[100] = {0};
//        double sum =0;
        success = 0;
        for(i=0; i<k-1;i++)
        {
                if(fuhao[i]=='*')
                {
                        int z = 0;
                        flag = 0;
                        for(z=j-1; z>i-1; z--)
                        {
                                temp[flag] = shuzi[z];
                                shuzi[z] = 0;
                                flag++;
                        }
                        flag = flag - 1;
                        sum = temp[flag]*temp[flag-1];

                         /*重构数字数组*/
                        shuzi[i] = sum;
                        printf("%d %d %d\n",flag,j,i);
                        for(z=i+1; z<j-1; z++,flag--)   
                        {        shuzi[z] = temp[flag-2];}
                        for(z=0; z<j-1; z++)
                        {        printf("%d ",shuzi[z]);}
                        j--;
                        success = 1;
                }
                if(fuhao[i]=='/')
                {
                        int z = 0;
                        flag = 0;
                        for(z=j-1; z>i-1; z--)
                        {
                                temp[flag] = shuzi[z];
                                shuzi[z] = 0;
                                flag++;
                        }
                        flag = flag - 1;
                        sum = temp[flag]/temp[flag-1];

                         /*重构数字数组*/
                        shuzi[i] = sum;
                        printf("%d %d %d\n",flag,j,i);
                        for(z=i+1; z<j-1; z++,flag--)   
                        {        shuzi[z] = temp[flag-2];}
                        for(z=0; z<j-1; z++)
                        {        printf("%.2lf ",shuzi[z]);}
                        j--;
                        success = 1;
                }
                /*重构符号数组*/
                if(success == 1)
                {
                        int f;
                        for(f=i; f<j; f++){
                        fuhao[f] = fuhao[f+1];
                        printf("%c ",fuhao[f]);
                        }
                        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[20] = {0};
        printf("输入运算表达式:");
        scanf("%s",arg);
        printf("%s",arg);                                               <------为啥没反应?
        if(arg[0]=='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端使用了线程,是不是线程问题?还是内存问题?
求大神知道!

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
2 [报告]
发表于 2012-11-01 15:13 |只看该作者
自己close自己的socket之后再写socket才会出SIGPIPE, 说实话这种错误永远也不应该发生,发生了就要反思自己的代码。

论坛徽章:
0
3 [报告]
发表于 2012-11-02 09:15 |只看该作者
注册一个信号处理函数——SIGTERM(即CTRL-C)

在该信号函数中使用shutdown关闭写端,可以继续读

论坛徽章:
0
4 [报告]
发表于 2012-11-02 09:46 |只看该作者
谢谢指点,其实ctrl-c的问题我已经解决,现在的问题是对离开标志‘q’   
为什么客户端没响应,而服务端就有响应

论坛徽章:
0
5 [报告]
发表于 2012-11-02 09:46 |只看该作者
回复 3# lxyscls_cu




谢谢指点,其实ctrl-c的问题我已经解决,现在的问题是对离开标志‘q’   
为什么客户端没响应,而服务端就有响应

   

论坛徽章:
0
6 [报告]
发表于 2012-11-02 12:47 |只看该作者
本帖最后由 lxyscls_cu 于 2012-11-02 12:48 编辑

{:3_189:}

论坛徽章:
1
技术图书徽章
日期:2013-10-29 15:46:41
7 [报告]
发表于 2012-11-02 16:58 |只看该作者
奇怪 用楼主的代码 我怎么能退出到shell啊...

论坛徽章:
0
8 [报告]
发表于 2012-11-04 09:27 |只看该作者
汗,可以用子进程来实现吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP