• 5241阅读
  • 0回复

急!一个基于udp通信得例子! [复制链接]

上一主题 下一主题
离线mikdkmgik
 
只看楼主 倒序阅读 楼主  发表于: 2010-06-10
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
为什么客户端可以向服务器发送信息,而服务器不能向客户端发送信息?

服务代码:
#include <QtGui>

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <string.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/wait.h>

#include <sys/stat.h>

#include <errno.h>

#include <pthread.h>

#include <QTimer>

#include "server.h"

#define BUFFER_SIZE 256

#define ECHO_PORT 2029

pthread_t m_thread;

struct hostent *client_addr;
int sockfd,opt=1;

socklen_t* len;
int flag=0;

struct sockaddr_in cliaddr;

char recvbuf[BUFFER_SIZE];

char buffer[BUFFER_SIZE];
int ret =0;

void *recvThread(void *data);

server::server(QWidget *parent)

        :QWidget(parent)

{

    SandRtextEdit=new QTextEdit;

    SendPushButton=new QPushButton(tr("&Send"));

    IpLineEdit=new QLineEdit("127.0.0.1");

    IpLineEdit->setFocus(Qt::BacktabFocusReason);

    textLineEdit=new QLineEdit;

    IpLabel=new QLabel(tr("Ip:"));

    IpLabel->setBuddy(IpLineEdit);



    QHBoxLayout *firstLayout=new QHBoxLayout;

    firstLayout->addWidget(IpLabel);

    firstLayout->addWidget(IpLineEdit);



    QHBoxLayout *secondLayout=new QHBoxLayout;

    secondLayout->addWidget(textLineEdit);

    secondLayout->addWidget(SendPushButton);



    QVBoxLayout *mainLayout=new QVBoxLayout;

    mainLayout->addWidget(SandRtextEdit);

    mainLayout->addLayout(firstLayout);

    mainLayout->addLayout(secondLayout);

    setLayout(mainLayout);



    memset(buffer,0xff,sizeof(buffer));
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

        {

                perror("ERROR opening socket");

                return;

        }

/*          if((ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0)
    {
        perror("ERROR setsockopt");
        return;
    }


*/
//printf("%d",sockfd);
if(( client_addr=gethostbyname(IpLineEdit->text().toUtf8().data())) == NULL)
        {
                herror("gethostbyname. ");
                return;
        }

        memset(&cliaddr, 0, sizeof(cliaddr));

        cliaddr.sin_family = AF_INET;

    cliaddr.sin_addr.s_addr =htonl(INADDR_ANY);
    cliaddr.sin_port = htons((uint16_t)ECHO_PORT);
    if ((ret = bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr))) < 0)
    {
        perror("ERROR on binding");
        return;
    }
    
    QTimer *m_DispTimer=new QTimer(this);

    connect(m_DispTimer,SIGNAL(timeout()),this,SLOT(handleDispTimer()));

    m_DispTimer->start(1000);

    pthread_create(&m_thread,NULL,recvThread,NULL);

    connect(SendPushButton,SIGNAL(clicked()),this,SLOT(buttonClicked()));

    

}


void *recvThread(void *data)

{

qDebug("create Thread succese");
        while(1)

        {    
//        len = (socklen_t*)sizeof(cliaddr);
        if((ret=recvfrom(sockfd,recvbuf,sizeof(recvbuf)-1,0,NULL,NULL))>0)

        {

            perror("recv fail");

        }

qDebug("recv succese");
                recvbuf[ret]=0;

                flag=1;

                usleep(1000);

        }

}





void server::handleDispTimer()

{

        if(1==flag)

           {

                flag=0;
        

                SandRtextEdit->append(QString(recvbuf));

           }

}



void server::buttonClicked()

{

    qDebug("button clicked");
    int ret=0;

        strcpy(buffer,textLineEdit->text().toUtf8().data());

        if((ret=sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)))<0)

        {

                perror("ERROR    writing to socket");

        }

     qDebug("send succese");  
     SandRtextEdit->append(buffer);

}
客户端代码:
#include <QtGui>
#include "clientchat.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <pthread.h>
#include <QTimer>

pthread_t m_thread;
int sockfd;
struct sockaddr_in servaddr;
struct hostent *server;
char recvbuf[100]={0};
int recvbyte=0;
int flag=0;
int ret=0;
void *recvThread();
#define ECHO_PORT 2029
void *recvThread(void *data);

ClientChat::ClientChat(QWidget *parent)
        :QWidget(parent)
{
    SandRtextEdit=new QTextEdit;
    SendPushButton=new QPushButton(tr("&Send"));
    IpLineEdit=new QLineEdit("127.0.0.1");
    IpLineEdit->setFocus(Qt::BacktabFocusReason);
    textLineEdit=new QLineEdit;
    IpLabel=new QLabel(tr("Ip:"));
    IpLabel->setBuddy(IpLineEdit);
    
    QHBoxLayout *firstLayout=new QHBoxLayout;
    firstLayout->addWidget(IpLabel);
    firstLayout->addWidget(IpLineEdit);
    
    QHBoxLayout *secondLayout=new QHBoxLayout;
    secondLayout->addWidget(textLineEdit);
    secondLayout->addWidget(SendPushButton);

    QVBoxLayout *mainLayout=new QVBoxLayout;
    mainLayout->addWidget(SandRtextEdit);
    mainLayout->addLayout(firstLayout);
    mainLayout->addLayout(secondLayout);
    setLayout(mainLayout);

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
                perror("ERROR opening socket");
                return;
        }


        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;

        
    QTimer *m_DispTimer=new QTimer(this);
    connect(m_DispTimer,SIGNAL(timeout()),this,SLOT(handleDispTimer()));
    m_DispTimer->start(1000);
    ret=pthread_create(&m_thread,NULL,recvThread,NULL);
    if(ret!=0)
    {
        perror("thread");
    }
    connect(SendPushButton,SIGNAL(clicked()),this,SLOT(buttonClicked()));
}

void *recvThread(void *data)
{
qDebug("create Thread succese");
    
        while(1)
        {
                if(recvbyte=recvfrom(sockfd,recvbuf,sizeof(recvbuf)-1,0,NULL,NULL)>0)
                {
                        perror("recv fail");
//                        break;
                }
qDebug("recv succese");
                recvbuf[recvbyte]='\0';
                flag=1;
                usleep(10000);
        }
}

void ClientChat::handleDispTimer()
{
    if(1==flag)
       {
        flag=0;
        SandRtextEdit->append(QString(recvbuf));
       }
}

void ClientChat::buttonClicked()
{
qDebug("button clicked");
    int ret=0;
    char buffer[100]={0};
    if((server = gethostbyname(IpLineEdit->text().toUtf8().data())) == NULL)
        {
                herror("gethostbyname. ");
                return;
        }
        qDebug("get host name succese");
        servaddr.sin_addr.s_addr=*(unsigned int*)server->h_addr;
        servaddr.sin_port = htons((uint16_t)ECHO_PORT);

    
    strcpy(buffer,textLineEdit->text().toUtf8().data());
    if((ret=sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr *)&servaddr,sizeof(servaddr)))<0)
    {
        perror("ERROR    writing to socket");
    }
qDebug("send succese");
     SandRtextEdit->append(buffer);
}
快速回复
限100 字节
 
上一个 下一个