关于socket的问题,请教各位

polly_polly 2013-07-31 10:09:29
问题描述:
我在程序里面起了两个线程,一个线程是客户端,一个线程是服务端,也就是说我的程序既是客户端,又是服务端。
问题:
在客户端线程里通过socket系统调用分配的socket句柄怎么会和服务器端线程accept系统调用返回的socket句柄相同呢,这样程序就会出现问题,不该关闭的时候被关闭了

请问各位大侠,是什么原因,有什么解决方法么。谢谢
...全文
455 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
polly_polly 2013-08-14
  • 打赏
  • 举报
回复
结帖了,谢谢各位的热心解答,已经找到问题了,是代码上的问题
mujiok2003 2013-08-06
  • 打赏
  • 举报
回复
引用 楼主 polly_polly 的回复:
在客户端线程里通过socket系统调用分配的socket句柄怎么会和服务器端线程accept系统调用返回的socket句柄相同呢,这样程序就会出现问题,不该关闭的时候被关闭了
我的理解是: socket只是对象句柄。在同一个进程内,客户端和服务端句柄相同是可以理解的。 任意端关闭,另一端保持open是没有意义的。如果需要, 再次创建socket即可。
polly_polly 2013-08-06
  • 打赏
  • 举报
回复
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); SO_REUSEADDR会有影响吗
max_min_ 2013-08-05
  • 打赏
  • 举报
回复
同一个进程, 不同线程作为客户端和服务端进行c/s通信

void* ClientFunc(void * param)
{

    int cli_sock = -1;
    int flags = -1;

    cli_sock = socket(AF_INET, SOCK_STREAM, 0);
    if( cli_sock < 0 )
    {
        perror("socket");
        return NULL;
    }
    struct sockaddr_in clientaddr;
    memset(&clientaddr, 0, sizeof(sockaddr_in));
    clientaddr.sin_family = AF_INET;
    clientaddr.sin_addr.s_addr = inet_addr("172.18.116.133");
    clientaddr.sin_port = htons(9999);
    if( connect(cli_sock, (struct sockaddr *)&clientaddr, sizeof(sockaddr_in)) < 0 )
    {
        perror("connect");
        return NULL;
    }
    flags = fcntl(cli_sock, F_GETFL, 0);
    fcntl(cli_sock, F_SETFL, flags|O_NONBLOCK);
    fd_set rset, wset;
    struct timeval tval;
    FD_ZERO(&rset);
    FD_SET(cli_sock, &rset);
    wset = rset;
    tval.tv_sec = 10;
    tval.tv_usec = 0;
    if ( select(cli_sock + 1, &rset, &wset, NULL, &tval)  < 0 )
    {
        printf("\n[%s]-[%d]: selec failed !", __func__, __LINE__);
        return NULL;
    }
    char buf[1024] = {0};
    char sendMsg[512] = {0};
    int writelen = 0;
    int readlen  = 0;
    while(1)
    {
        readlen = read(cli_sock, buf, sizeof(buf));
        printf(" sever:%s\n", buf);
        writelen = write(cli_sock, "Hello sever!", 1024);
    }
}

 while(1)
    {
        //用select()函数进行accept是否有客户端连接到来的轮询,否则程序会可能一直在这里阻塞,
        //当没有客户端到来的时候,用户层不能进行处理
        FD_ZERO(&fd_r);
        FD_ZERO(&fd_w);
        FD_SET(ser_sock, &fd_r);
        FD_SET(ser_sock, &fd_w);
        tvv.tv_sec = 2;
        tvv.tv_usec = 0;

        Ret = select(ser_sock + 1, &fd_r, &fd_w, NULL, &tvv);

        printf("\n [%s]-[%d]: Ret = %d \n", __func__, __LINE__, Ret);
        switch( Ret )
        {
            case -1:
            case 0:
                continue;
            default:
                break;

        }
        ///accept 返回每个不同客户端的socket
        cli_sock = accept(ser_sock, (struct sockaddr *)& clieaddr_in, &socklen);

        if( cli_sock < 0 )
        {
            perror("accept");
            return -1;
        }
        m_ClientNum ++;
        //连接上的的某一个客户端信息的交互
        char buf[1024] = {0};
        sprintf(buf, "Hello client[%d], thanks for you come in!", m_ClientNum);
        write(cli_sock, buf, 1024);

        pthread_t pthreadId;
        pthread_t clientpthreadId;
        PThreadParam* stThread = new PThreadParam;
        stThread->sockfd = cli_sock;
//      pthread_create(&pthreadId, NULL, &serverwrite, (void*)stThread);

        //测试客户端线程函数
        pthread_create(&clientpthreadId, NULL, &ClientFunc, NULL);
         while(1)
        {
         read(cli_sock, buf, sizeof(buf));
            printf(" client:%s\n", buf);

        }
    }

赵4老师 2013-08-05
  • 打赏
  • 举报
回复
学习使用抓包软件才是帖主急需。
polly_polly 2013-08-05
  • 打赏
  • 举报
回复
没有啊,我客户端线程连接的是另外的服务器地址和端口的
大尾巴猫 2013-08-02
  • 打赏
  • 举报
回复
你检查下看看,是不是你客户端线程的socket连接到你自己的服务端线程上了。
polly_polly 2013-08-02
  • 打赏
  • 举报
回复
没人给我提供解决方案吗
polly_polly 2013-08-01
  • 打赏
  • 举报
回复
引用 16 楼 lilin_colin 的回复:
整这么麻烦干什么? 要么用进程,要么就分开写client/server,两个线程怎么能模拟呢?最主要你的sockfd怎么解决的?
为什么好多人说不能用两个线程写客户端和服务器端呢?什么原因呢 我在socket系统调用和accept系统调用的时候加了互斥锁了,还是不行
大尾巴猫 2013-08-01
  • 打赏
  • 举报
回复
我也搞不清了,你用一台机器还是2台机器做测试的?
polly_polly 2013-08-01
  • 打赏
  • 举报
回复
引用 15 楼 ananluowei 的回复:
[quote=引用 13 楼 polly_polly 的回复:] 还是不行啊 怎么加锁啊?救命啊 pthread_mutex_lock(&lock_getsocket); if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { printf("Create Socket Failed!\n"); exit(1); } pthread_mutex_unlock(&lock_getsocket); pthread_mutex_lock(&lock_getsocket); listenfd = socket(AF_INET, SOCK_STREAM, 0); pthread_mutex_unlock(&lock_getsocket); pthread_mutex_lock(&lock_getsocket); connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &socklen); //等待客户端进行链接 pthread_mutex_unlock(&lock_getsocket);
先不管加不加锁 connfd是你accept得到的和客户端通信的socket 那么你自己做客户端的socket在哪里定义的[/quote] socket都是在线程函数里面定义的啊
Xiaona_Song 2013-07-31
  • 打赏
  • 举报
回复
应该是你哪里写错了,你看这的socket例子吧: http://download.csdn.net/detail/geoff08zhang/4571358
自信男孩 2013-07-31
  • 打赏
  • 举报
回复
用两个线程去模拟是不行的哦。
大尾巴猫 2013-07-31
  • 打赏
  • 举报
回复
不明白你怎么做的。 服务端accept返回的socket怎么会和自己作为客户端去connect的socket是同一个的。
赵4老师 2013-07-31
  • 打赏
  • 举报
回复
用两个进程代替两个线程。 《Unix编程艺术》
polly_polly 2013-07-31
  • 打赏
  • 举报
回复
具体怎么解决呢
max_min_ 2013-07-31
  • 打赏
  • 举报
回复

它们本身也不是相同的阿!
一个是客户端的套接字sock,绑定了你输入的服务器的ip地址和端口,这个socket,只是在这个ip和对应的端口作I/O操作
服务器是客户端accept返回的sock套接字,它只是处理对应客户端的I/O操作的!

因为是同一个进程里,所以你要保证它们在通信的时候 各自的 socket都是有效的!
zilaishuichina 2013-07-31
  • 打赏
  • 举报
回复
显然是你代码写错了。。。。
qq120848369 2013-07-31
  • 打赏
  • 举报
回复
代码有问题。
绯红女王 2013-07-31
  • 打赏
  • 举报
回复
整这么麻烦干什么? 要么用进程,要么就分开写client/server,两个线程怎么能模拟呢?最主要你的sockfd怎么解决的?
加载更多回复(8)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧