Socket Programming Practice (--socket) API Encapsulation (2)

Source: Internet
Author: User
Tags htons

Note: This blog and the next blog <socket Programming Practice (>), as a result of more code, so divided into two, this article, mainly on the previous explanation of the socket class enhancement, the next one mainly on how to use this enhanced version of the Socket class ( Implementation and use of the Serversocket/clientsocket Class)!

Source of thought:

1)http://www.cnblogs.com/-Lei/archive/2012/09/04/2670964.html

2)http://blog.csdn.net/column/details/linux66.html

3)http://blog.csdn.net/column/details/zjf666.html

What to modify:

1) modified the access rights of several member functions of the socket class (changed from public to protected, so that the socket class can inherit, but not allowed to use privately)

2) added Close, getaddr, Getport member functions to make it easier to use (as you can see in the server-side code in the next section)

3) The Send/receive function is implemented with the famous WRITEN/READN (formerly the Read/write system Call), which strengthens the fault tolerance of the socket class.

4) Added exception handling, so that when writing error-prone code, we can emancipate our minds and not always consider what happens when the function call goes wrong!


Socket.h
#ifndef socket_h_included#define socket_h_included#include <sys/socket.h> #include <sys/types.h># Include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string> #include    <string.h> #include <fcntl.h>class socket{public:socket ();  Virtual ~socket (); Virtual Destructior//protect The Function, only used to Server Or clientprotected:bool Create ();  Create a socket, server & client can use/**server**/bool Bind (int port) const; Bind a port bool Listen (int backlog = somaxconn) const;    Start to listen bool Accept (socket& clientsocket) const;    Accept a connect/**client**/bool Connect (const std::string& host, int port); /** Data Transmission:return=0:write or read nothing (if receive = = 0,peer Connect closed) RETURN&LT;0:WR ITE error (errno is set) Return>0:write success (return value is the bytes has send/receive) **/size_t Se nd (const SOCKET&Amp    Socket, const std::string& message) const; size_t Receive (const socket& Socket, std::string& message) Const;public:/***all can use!***///flag:true=s    Etnonblock, false=setblock bool Setnonblocking (BOOL flag);    Return:true-setsuccess bool Setreuseaddr ();    Test for M_SOCKFD;    BOOL IsValid () const;    Close the socket bool Close ();p ublic:std::string getaddr ();    int Getport () const;private://use m_sockfd to record the result of the function socket int M_SOCKFD;    struct sockaddr_in m_address; Define the max bytes to send/write static const int bufsiz = 1024*10;}; #endif//socket_h_included

Socket.cpp
#include "Socket.h" static ssize_t readn (int fd, void *buf, size_t count); static ssize_t writen (int fd, const void *buf, si ze_t count);    Socket::socket (): M_SOCKFD ( -1) {}socket::~socket () {if (IsValid ()) {close (M_SOCKFD);        }}bool Socket::close () {if (IsValid ()) {:: Close (M_SOCKFD);        M_SOCKFD =-1;    return true; } return false;}    BOOL Socket::create () {m_sockfd = Socket (af_inet,sock_stream,0);    if (IsValid ()) return true; return false;} Bind a server port at the Serverbool socket::bind (int port) const{if (!    IsValid ()) {return false;    } struct sockaddr_in serveraddr;    serveraddr.sin_family = af_inet;    Serveraddr.sin_port = htons (port);    SERVERADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);  if (Bind (M_SOCKFD, (const struct sockaddr *) &serveraddr, sizeof (struct sockaddr)) = =-1) {return    False } return true; BOOL Socket::listen (int backlog) const{if (! IsValid ()) {RETUrn false;    } if (listen (m_sockfd,backlog) = =-1) {return false; } return true; BOOL Socket::accept (Socket &clientsocket) const{if (!    IsValid ()) {return false;    } socklen_t clientaddrlength = sizeof (clientsocket.m_address);                                   CLIENTSOCKET.M_SOCKFD = Accept (M_SOCKFD, (struct sockaddr *) (&clientsocket.m_address),    &clientaddrlength);    if (CLIENTSOCKET.M_SOCKFD = =-1) {return false; } return true; Clientbool socket::connect (const std::string &serverhost, int serverport) {if (!    IsValid ()) {return false;    } struct sockaddr_in serveraddr;    serveraddr.sin_family = af_inet;    SERVERADDR.SIN_ADDR.S_ADDR = inet_addr (Serverhost.c_str ());    Serveraddr.sin_port = htons (ServerPort);        if (Connect (M_SOCKFD, const struct sockaddr *) (&AMP;SERVERADDR), sizeof (struct sockaddr)) = =-1) {    return false; } return true; size_t Socket::send (constSocket &peersocket, const std::string &messages) const{struct transstruct {size_t buflen;   Save the true message content length char buf[bufsiz];    The message content that is really to be sent} sendstruct;    Sendstruct.buflen = Messages.length ();    strncpy (Sendstruct.buf,messages.c_str (), Sendstruct.buflen); ssize_t nwrited = writen (peersocket.m_sockfd,&sendstruct, sendstruct.buflen+sizeof (size_t))    ;    if (nwrited = = 0) {return 0;    } else if (nwrited = =-1) {return-1; } return nwrited;}    size_t socket::receive (const Socket &peersocket, std::string &messages) const{size_t messagelen = 0;    if (Readn (peersocket.m_sockfd,&messagelen,sizeof (size_t)) = =-1) {return false;    } Char Buf[bufsiz];    memset (buf,0,sizeof (BUF));    Messages.clear ();    ssize_t nread = Readn (Peersocket.m_sockfd,buf,messagelen);    if (nread = = 0) {return 0;    } else if (nread = =-1) {return-1; } MessaGES = BUF; return nread;} Set the SOCKFD nonblockedbool socket::setnonblocking (BOOL flag) {if (IsValid ()) {int opts = FCNTL (m_sockfd        , F_GETFL);        if (opts = =-1) {return false;        } if (flag) {opts |= o_nonblock;        } else {opts &= ~o_nonblock;    } return Fcntl (m_sockfd,f_setfl,opts); } return false;}        Set the Address Reusedbool socket::setreuseaddr () {if (IsValid ()) {int on = 1;        if (setsockopt (m_sockfd,sol_socket,so_reuseaddr,&on,sizeof (on)) = =-1) {return false;        } else {return true; }} return false;} BOOL Socket::isvalid () const{//if m_sockfd isn't call Create, M_SOCKFD = =-1//else m_sockfd! =-1 return M_SOC KFD! =-1;}    std::string socket::getaddr () {if (IsValid ()) {return Inet_ntoa (M_ADDRESS.SIN_ADDR); } return std::string ();} int SOCKET::GETPORT () const{if (IsValid ()) {return ntohs (m_address.sin_port); } return-1;}    static ssize_t readn (int fd, void *buf, size_t count) {size_t nleft = count;    ssize_t nread = 0;    Char *ptr = Static_cast<char *> (BUF);            while (Nleft > 0) {if (nread = Read (fd,ptr,nleft)) < 0) {//nothing has read!!!  if (Nleft = = count) {return-1;  Error} else {break;  Error, return amount read so far}} else if (nread = = 0) {break;        EOF}//continue to read nleft-= Nread;    PTR + = nread; } return count-nleft;}    static ssize_t writen (int fd, const void *buf, size_t count) {size_t nleft = count;    ssize_t Nwritten;    const char *ptr = static_cast<const char *> (BUF);        while (Nleft > 0) {if (Nwritten = Write (fd,ptr,nleft)) < 0) {    Nothing has the write if (Nleft = = count) {return-1;  Error} else {break;  Error, return amount write so far}} else if (Nwritten = = 0) {break;        EOF} nleft-= Nwritten;    PTR + = Nwritten; } return Count-nwritten;}

SocketException.h
#ifndef socketexception_h_included#define socketexception_h_included//Exception handling Class (the next section will use ...) Class Socketexception{public:    socketexception (const std::string &description):        m_description ( Description) {}    ~socketexception () {}    std::string description ()    {        return m_description;    } Private:    std::string m_description;}; #endif//socketexception_h_included

Socket Programming Practice (--socket) API Encapsulation (2)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.