注:这一片博客与上一篇博客<Socket编程实践(19)>合为一篇,由于代码较多,所以分为两篇,本篇为下篇,这一篇主要讲解怎样使用上一篇开发的增强版的Socket类(ServerSocket/ClientSocket类的实现与使用)!
思想来源:
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
亮点内容:
1)添加了异常处理(在ServerSocket/ClientSocket继承父类Socket的同时,也处理了父类函数调用可能出现的错误,并throw出来,由使用这两个类的代码进行处理),让我们在编写易出错的代码时,可以解放思想,不用一直考虑该函数调用出错会发生什么情况!
2)SeverSocket/ClientSocket类重写覆盖了父类Socket的Send/Receive成员函数,使得这两个函数更加易用(从client端的代码中可看出)
3)在Server端代码中,遵循Peer Connect one Process, 添加了fork调用,每一个子进程处理一个连接
4)在Server端添加了捕获SIGCHLD的代码,防止出现僵尸进程.
5)在Server/Client端代码中添加try/catch语句,处理出错情况.
//In ServerSocket.h
#ifndef SERVERSOCKET_H_INCLUDED
#define SERVERSOCKET_H_INCLUDED
#include "Socket.h"
#include "SocketException.h"
class ServerSocket : public Socket
{
public:
ServerSocket(int port, int backlog = SOMAXCONN);
virtual ~ServerSocket();
void Accept(Socket &clientSocket) const;
/**Over write the Send & Receive**/
size_t Send(const Socket& socket, const std::string& message) const;
size_t Receive(const Socket& socket, std::string& message) const;
};
#endif // SERVERSOCKET_H_INCLUDED//In ServerSocket.cpp
#include "ServerSocket.h"
ServerSocket::ServerSocket(int port, int backlog)
{
if (!Socket::Create())
{
throw SocketException("Create server socket error");
}
if (!Socket::Bind(port))
{
throw SocketException("Sever socket bind a port error");
}
if (!Socket::Listen(backlog))
{
throw SocketException("Server socket listen error");
}
}
ServerSocket::~ServerSocket()
{
}
void ServerSocket::Accept(Socket &clientSocket) const
{
if (!Socket::Accept(clientSocket))
{
throw SocketException("Accept a connect error");
}
}
size_t ServerSocket::Send(const Socket &socket, const std::string &message) const
{
size_t nSend =
Socket::Send(socket,message);
if (nSend < 0)
{
throw SocketException("Send messages error");
}
return nSend;
}
size_t ServerSocket::Receive(const Socket &socket, std::string &message) const
{
size_t nRead =
Socket::Receive(socket,message);
if (nRead == 0)
{
throw SocketException("Peer connect closed");
}
else if (nRead < 0)
{
throw SocketException("Receive messages error");
}
return nRead;
}//In ClientSocket.h
#ifndef CLIENTSOCKET_H_INCLUDED
#define CLIENTSOCKET_H_INCLUDED
#include "Socket.h"
#include "SocketException.h"
class ClientSocket : public Socket
{
public:
ClientSocket(const std::string &serverHost, int port);
~ClientSocket();
size_t Send(const std::string& message) const;
size_t Receive(std::string& message) const;
};
#endif // CLIENTSOCKET_H_INCLUDED//In ClientSocket.cpp
#include "ClientSocket.h"
ClientSocket::ClientSocket(const std::string &serverHost, int port)
{
if (!Socket::Create())
{
throw SocketException("Create client socket error");
}
if (!Socket::Connect(serverHost,port))
{
throw SocketException("Connect server socket error");
}
}
ClientSocket::~ClientSocket()
{
}
size_t ClientSocket::Send(const std::string &message) const
{
size_t nSend =
Socket::Send(static_cast<const Socket&>(*this),message);
if (nSend < 0)
{
throw SocketException("Send messages error");
}
return nSend;
}
size_t ClientSocket::Receive(std::string &message) const
{
size_t nRead =
Socket::Receive(static_cast<const Socket&>(*this),message);
if (nRead == 0)
{
throw SocketException("Peer connect closed");
}
else if (nRead < 0)
{
throw SocketException("Receive messages error");
}
return nRead;
}//server.cpp
#include "ServerSocket.h"
#include "SocketException.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <iostream>
using namespace std;
void onSigChild(int signalNumber)
{
if (signalNumber == SIGCHLD)
{
while (wait(NULL) != -1)
;
}
}
int main()
{
signal(SIGCHLD,onSigChild);
cout << "Server Running..." << endl;
try
{
ServerSocket server(9001);
while (true)
{
Socket newSocket;
server.Accept(newSocket);
cout << "Client information:" << endl;
cout << ‘\t‘ << newSocket.getAddr() << endl;
cout << ‘\t‘ << newSocket.getPort() << endl;
pid_t pid = fork();
if (pid == -1)
{
perror("fork error");
}
else if (pid == 0)
{
server.Close();
while (true)
{
try
{
string messages;
server.Receive(newSocket,messages);
cout << messages << endl;
server.Send(newSocket,messages);
}
catch (SocketException &ex)
{
cerr << ex.Description() << endl;
exit(0);
}
}
}
else
{
newSocket.Close();
}
}
}
catch (SocketException &ex)
{
cerr << ex.Description() << endl;
}
return 0;
}//client.cpp
#include <iostream>
#include <string>
#include "ClientSocket.h"
#include "SocketException.h"
using namespace std;
int main()
{
cout<<"Running client...."<<endl;
try
{
ClientSocket clientSocket("127.0.0.1",9001);
try
{
string messages;
while (getline(cin,messages))
{
if (messages.length() == 0)
{
messages.append("\n");
}
clientSocket.Send(messages);
messages.clear();
clientSocket.Receive(messages);
cout << messages << endl;
}
}
catch (SocketException &ex)
{
cerr << ex.Description() << endl;
}
}
catch (SocketException &ex)
{
cerr << ex.Description() << endl;
}
return 0;
}运行截图:
附-Makefile
CC = g++
CPPFLAGS = -Wall -g -pthread
BIN = server client
SOURCES = $(BIN.=.cpp)
.PHONY: clean all
all: $(BIN)
$(BIN): $(SOURCES) Socket.cpp ServerSocket.cpp ClientSocket.cpp
clean:
-rm -rf $(BIN) bin/ obj/ coreSocket编程实践(20) --Socket API封装(3)
原文地址:http://blog.csdn.net/zjf280441589/article/details/41896873