socket 客户端 linux

/* File Name: client.c */
 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <iostream>

using namespace std;


#define MAXLINE 4096

#define err_exit(m) \
     do \
	 {\
		perror(m);\
		exit(EXIT_FAILURE);\
	 }while(0)


struct Packet    
{    
    unsigned int      msgLen;     //数据部分的长度(注:这是网络字节序)    
    char            text[1024]; //报文的数据部分    
};  




/**实现:  
这两个函数只是按需多次调用read和write系统调用直至读/写了count个数据  
**/    
/**返回值说明:  
    == count: 说明正确返回, 已经真正读取了count个字节  
    == -1   : 读取出错返回  
    <  count: 读取到了末尾  
**/    
ssize_t readn(int fd, void *buf, size_t count)    
{    
    size_t nLeft = count;    
    ssize_t nRead = 0;    
    char *pBuf = (char *)buf;    
    while (nLeft > 0)    
    {    
        if ((nRead = read(fd, pBuf, nLeft)) < 0)    
        {    
            //如果读取操作是被信号打断了, 则说明还可以继续读    
            if (errno == EINTR)    
                continue;    
            //否则就是其他错误    
            else    
                return -1;    
        }    
        //读取到末尾    
        else if (nRead == 0)    
            return count-nLeft;    
    
        //正常读取    
        nLeft -= nRead;    
        pBuf += nRead;    
    }    
    return count;    
}    

/**返回值说明:  
    == count: 说明正确返回, 已经真正写入了count个字节  
    == -1   : 写入出错返回  
**/    
ssize_t writen(int fd, const void *buf, size_t count)    
{    
    size_t nLeft = count;    
    ssize_t nWritten = 0;    
    char *pBuf = (char *)buf;    
    while (nLeft > 0)    
    {    
        if ((nWritten = write(fd, pBuf, nLeft)) < 0)    
        {    
            //如果写入操作是被信号打断了, 则说明还可以继续写入    
            if (errno == EINTR)    
                continue;    
            //否则就是其他错误    
            else    
                return -1;    
        }    
        //如果 ==0则说明是什么也没写入, 可以继续写    
        else if (nWritten == 0)    
            continue;    
    
        //正常写入    
        nLeft -= nWritten;    
        pBuf += nWritten;    
    }    
    return count;    
}    

bool sendMessage(int sockfd,Packet buf){
    unsigned int lenHost = strlen(buf.text);  
    buf.msgLen = htonl(lenHost);  
    if (writen(sockfd, &buf, sizeof(buf.msgLen)+lenHost) == -1)  
        return false;
    return true;
}


int InitStart(const char* ip,int port){
    int sockfd;
    struct sockaddr_in    servaddr;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return -1;

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    if(inet_pton(AF_INET, ip, &servaddr.sin_addr) <= 0)
        return -1;
        
    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
        return -1;

    return sockfd;
}

void hander(int sockfd,Packet buf){
    cout<<"这里是处理函数"<< buf.text<<endl;
    cin>>buf.text;
    sendMessage(sockfd,buf);
}

bool ReadMessage(int sockfd){

    struct Packet buf;  
    memset(&buf, 0, sizeof(buf));  

        //首先读取首部  
        ssize_t readBytes = readn(sockfd, &buf.msgLen, sizeof(buf.msgLen));  
        if (readBytes == -1){
            cout<<"read socket error"<<endl;
            close(sockfd);
            return false;
        }else if (readBytes != sizeof(buf.msgLen))  
        {  
            cout << "server connect closed... \nexiting..." << endl;  
            close(sockfd);
            return false;
        }  
  
        //然后读取数据部分  
        int lenHost = ntohl(buf.msgLen);  
        readBytes = readn(sockfd, buf.text, lenHost);  
        if (readBytes == -1){  
            err_exit("read socket error");  
            close(sockfd);
            return false;
        }else if (readBytes != lenHost)  
        {  
            cerr << "server connect closed... \nexiting..." << endl;  
            close(sockfd);
            return false;

        }  
        
        hander(sockfd,buf);
        //cout << buf.text<<endl;  
        return true;
}

int main(int argc, char** argv)
{
 

    int sockfd = InitStart("127.0.0.1",8000);
    if(sockfd == -1){
        cout<<"服务器连接失败!"<<endl;
        return 0;
    }
    Packet buf;
    cin>>buf.text;
    sendMessage(sockfd,buf);
    while (ReadMessage(sockfd));
    cout<<"exit"<<endl;
    close(sockfd);
    exit(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值