免费注册 查看新帖 |

Chinaunix

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

[C++] linux下socket用C++编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-24 18:38 |只看该作者 |倒序浏览
本帖最后由 linsanko 于 2011-08-24 20:13 编辑

C++编写一个服务端程序。。。调用accept函数的出错,用c写的时候也是这样写的,但不知道为什么就错了。。。难道是用了类的原因?
很感谢drangon看了之后提的建议。
/***目的:生成服务端程序
***出错的位置目前显示出:调用accept函数的时候返回为-1,也就是client_sockfd的值没能够申请成功。
***本程序采用UDP协议。所以就没监听。(监听listen函数好像只面向有连接)
以下是代码:
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>

#define BUFSIZE (1024*16)
#define QUEUE_LEN 10
typedef int SOCKET;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned int WORD;
typedef int BOOL;
#define TRUE 1
#define FALSE 0
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1

class CGzUdp
{
public:
        CGzUdp();
        ~CGzUdp();
public:
        unsigned char g_buffer[BUFSIZE];
protected:
        SOCKET                service_sockfd;
        SOCKET                client_sockfd;  
        WORD                m_wLocalPort;  
        int                            m_iSocketId;
        BOOL                m_bIsReceiving;
        pthread_t                threadID;   //这个是线程ID号
protected:
        virtual void  ReceivingLoop(void); //线程入口函数
        static void *ReceivingThrd(void * pParam); //这个是接收循环,也是线程实际上去处理的函数

public:
        BOOL Init(int socketId);
        void SetLocalPort(WORD inPort);
        BOOL CreateSender(void);
        void DeleteSender(void);
        BOOL CreateReceiver(void);
        void DeleteReceiver(void);  

        BOOL StartReceiving(void);
        void StopReceiving(void);

};


int main( void )
{
        CGzUdp m_pCommandUdp;
        m_pCommandUdp.Init(0);
        WORD m_wOcuPort = 10012;

        m_pCommandUdp.SetLocalPort(m_wOcuPort);
        m_pCommandUdp.CreateReceiver();  
        m_pCommandUdp.StartReceiving();
               sleep(5);
               return 0;
}


CGzUdp::CGzUdp()
{
        service_sockfd = INVALID_SOCKET;
        client_sockfd   = INVALID_SOCKET;
        m_wLocalPort   = 10090;
                threadID = 0;
        m_bIsReceiving = FALSE;
}

CGzUdp::~CGzUdp()
{
        DeleteSender();
        DeleteReceiver();
        StopReceiving();

}

BOOL CGzUdp::Init(int socketID)
{
        m_iSocketId = socketID;
        return TRUE;
}

void CGzUdp::SetLocalPort(WORD inPort)
{
        m_wLocalPort = inPort;
}

void CGzUdp:eleteSender(void)
{
        if (client_sockfd != INVALID_SOCKET)
        {
                   close(client_sockfd);
            client_sockfd = INVALID_SOCKET;
        }
}

BOOL CGzUdp::CreateReceiver(void)
{
        DeleteReceiver();
        service_sockfd = socket(AF_INET, SOCK_DGRAM, 0); //声明数据报流
        if (service_sockfd != INVALID_SOCKET)
        {
                BOOL flag = TRUE;
                int ret = setsockopt(service_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(flag));
                if (ret == SOCKET_ERROR)
                {
                        DeleteReceiver();
                        return FALSE;
                }

            struct sockaddr_in serv_addr;
                    serv_addr.sin_family      = AF_INET;
            serv_addr.sin_addr.s_addr = INADDR_ANY;//htonl();
            serv_addr.sin_port        = htons(m_wLocalPort);
            ret = bind(service_sockfd, (struct sockaddr*) &serv_addr, sizeof(sockaddr));
            if (ret == SOCKET_ERROR)
            {
               cout<<"bind error!"<<endl;
                   DeleteReceiver();
                   return FALSE;
            }

                int nZero=0;
                setsockopt(service_sockfd,SOL_SOCKET,SO_RCVBUF,(char *)&nZero,sizeof(int));
                int nNetTimeout = 80;
                setsockopt(service_sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
                return TRUE;
        }
        return FALSE;
}

void CGzUdp:eleteReceiver(void)
{
        if (service_sockfd != INVALID_SOCKET)
        {
        close(service_sockfd);
                service_sockfd = INVALID_SOCKET;
        }
}

//开启接收线程
BOOL CGzUdp::StartReceiving(void)
{
        if (service_sockfd == INVALID_SOCKET)
        {
                CreateReceiver();
        }

        if (service_sockfd != INVALID_SOCKET)
        {
                if (m_bIsReceiving)
                {
                        return TRUE;
                }       
    int m_hRcvThread;
    m_hRcvThread = pthread_create(&threadID, NULL, ReceivingThrd, this); //创建线程
                return (threadID != 0);
        }
        return FALSE;
}

void CGzUdp::StopReceiving(void)
{
        if (threadID != 0)
        {         
                     pthread_join(threadID ,NULL);
        }
        close(service_sockfd);
}

void * CGzUdp::ReceivingThrd(void * pParam)
{
        CGzUdp * pController = (CGzUdp*) pParam;
        pController->ReceivingLoop();
        return 0;
}

//接收循环
void CGzUdp::ReceivingLoop(void)
{
        struct sockaddr_in  addr_client;
        long bytes = 0;
                 int addr_cli_len = sizeof(struct sockaddr_in);
                 //这个地方是目前出错的地方:不知道调用accept()为什么没能成功,参数应该都是对的吧?
        client_sockfd = accept(service_sockfd, (struct sockaddr *)&addr_client, (socklen_t *)&addr_cli_len);
        if(client_sockfd == -1)
        {
                cout<<"accept error!"<<endl;
                exit(1);
        }

        m_bIsReceiving = TRUE;
        while (m_bIsReceiving)
        {                               
        bytes = recvfrom(client_sockfd, g_buffer, BUFSIZE, 0, (struct sockaddr *)&addr_client, (socklen_t *)&addr_cli_len);

                if (bytes == SOCKET_ERROR || bytes == 0)
                    cout<<"receiving error!"<<endl;
                else
            cout<<g_buffer<<endl;
        }
        close(client_sockfd);
    pthread_exit(0);

}

论坛徽章:
0
2 [报告]
发表于 2011-08-24 18:47 |只看该作者
不写明出错位置,不写明预计结果和实际结果,大部分人估计都是懒得看,最郁闷的是把代码跑了一遍,还不知道是什么错误,或者发现几个错误,都不是楼主想问的错误。

如果有预期结果和实际结果,有不少情况是不用跑一遍,都能提出一些想法和建议的。或者结果比较奇怪,大家也会有好奇心去跑一遍看看到底是什么回事。

懒的把代码跑一遍又闲的长篇大论的,那是不正常的

论坛徽章:
0
3 [报告]
发表于 2011-08-24 20:01 |只看该作者
回复 2# drangon


    恩。。。谢谢你的提醒。。。第一次这样发帖,不知道注意些什么。。。
   错在调用accept函数的时候,不知道为什么调用失败了。。。在C下也是这样写的调用的,也没有出错啊。。。

论坛徽章:
0
4 [报告]
发表于 2011-08-24 21:11 |只看该作者
用\[code\] 和 \[/code\] 把代码括起来 发代码大时候
我只想说这个  

论坛徽章:
0
5 [报告]
发表于 2011-08-25 08:34 |只看该作者
既然调用函数失败,就把errno打印出来,根据errno,自己就知道发生什么错误了,没有errno,谁也不知道发生什么错误,就算闲的慌把代码输入跑一遍,也不见得会出错,出错也不一定是跟你一样的错。

论坛徽章:
0
6 [报告]
发表于 2011-08-25 09:45 |只看该作者
你的代码里面有一个很基本的问题,的socket类型是 SOCK_DGRAM (数据报,无连接),而 accept 只能用于面向连接的 socket 类型 (比如:SOCK_STREAM)。

论坛徽章:
0
7 [报告]
发表于 2011-08-25 10:15 |只看该作者
回复 4# zcheung


    没明白你说这个。。。麻烦再解释一下吧

论坛徽章:
0
8 [报告]
发表于 2011-08-25 10:15 |只看该作者
回复 5# drangon


    恩。。。好的。。。谢谢你的建议。。。

论坛徽章:
0
9 [报告]
发表于 2011-08-25 10:18 |只看该作者
楼主,都没有listen,哪来什么accept了?
服务器端口绑定以后,等着收数就行了!{:2_168:}

论坛徽章:
0
10 [报告]
发表于 2011-08-25 10:19 |只看该作者
回复 6# seaquester


    恩。。。原先还用了listen(),后来发现listen也只能监听面向连接的数据报。那么accept()也只能接收面向连接。。。那么如何来接收/发送数据报socket呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP