为什么客户端可以向服务器发送信息,而服务器不能向客户端发送信息?
服务代码:
#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);
}