QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1104|回复: 11

网络模块的源代码……

[复制链接]
发表于 2003-10-28 17:13:34 | 显示全部楼层 |阅读模式
本来我说过这个月要拿出一个最初的源代码,现在先把它发上来,还没有编译,请大家找错啊~
rar格式的文件,把后缀名jpg去掉即可~   

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 发表于 2003-10-28 17:29:22 | 显示全部楼层
好像不行啊,那我只好将源代码全部贴上来了~
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:37:17 | 显示全部楼层

说明文档

在网络应用开发中,随着需求的改变及性能的提高,程序变得越来越复杂,越来越大。从而导致编译和连接时间长。为更有效地重用代码,应该建立相应的类库。库是包括不同对象的文件。它可作为一个实体进行连接,因而可以极大地提高连接速度。Linux系统可以创建两种库:静态连接库和动态连接库。
为了有效地重用代码,我们采用面向对象地编程方法来实现套接字类库。
由于Linux系统提供的网络API均是C库形式,因此,第一次必须将C形式地系统调用封装到相应地类中,即Wrapper类。在此基础上建立一些公用类。然后,可以根据实际应用的情况,创建一些应用类。另外,还可以创建一些基类用于类的管理或特殊用途。
1 . Wrapper类
根据以上思想,我们建立套接字的Wrapper类,主要包括以下一些类。
        MySocket类:封装基础的套接字系统调用,并且实现异常处理。为了满足不同需要,提供了多种形式的函数调用。
        MyThread类:封装了POSIX线程的系统调用以实现多线程,并且提供了简单明了的方法来产生线程。
        MyMutex类:提供实现互斥锁的基本方法。
        MyCondition类:提供实现条件变量的基本方法。
2 . 公用类
公用类主要包括以下类。
        TcpServThr类:提供实现基于TCP多线程服务器的方法。
        TcpCliThr类:提供实现基于TCP多线程客户的方法。
        MessageQue类:提供实现带互斥锁的队列的方法。
3 . 应用类
        GameServer类:网络游戏的服务器类,是一个TCP多线程并发服务器。
        GameClient类:网络游戏的客户类,是一个基于TCP多线程客户。
另外,还实现了一个基类Thread_interface,用于更灵活地产生线程。
4 . 各类的关系
从图中可以看出,TcpServThr类和TcpCliThr类从MySocket继承而来,可以方便地实现网络操作。它们包括以下两个内部类。
        Receiver类:用于产生接收客户数据地线程。
        Sender类:用于产生向客户发送数据地线程。
这两个内部类从MyThread继承而来,用于实现多线程。由于这两个内部类仅为了方便地使用TcpServThr类和TcpCliThr类,并不具有普遍意义,因此将它们定义为内部的。在MessageQue类中引用了MyMutex类,以实现互斥锁来保护队列数据的完整性。
可以通过引用关系或继承关系生成新的类,例如继承MySocket类以生成多进程并发服务器。也可以对已有的类进行修改从而增加新的功能,使其更加完善。由此看出,建立套接字类库能迅速地产生新的应用,也能方便地对原系统进行升级,程序也具有良好的结构,便于阅读和调试,从而极大地提高开发效率。


套接字系统调用:MySocket类
MySocket类是该套接字类库的核心,它封装了与套接字相关的主要系统调用。其源代码见:
………………
1.        MySocket类的成员变量
在一个类中,成员函数代表了该类的特性及状态。MySocket类的成员变量存放与套接字相关的信息,其内容如下:
        address_family:存放地址簇,如AF_INET。
        protocol_family:存放协议簇,如IPPROTO_TCP。
        socket_type:套接字类型,如SOCK_STREAM、SOCK_DGRAM。
        port_number:端口号。
        Mysocket:套接字的描述符。对于SOCK_STREAM类型的套接字为侦听套接字描述符。
        conn_socket:连接套接字描述符。对于SOCK_DGRAM类型的套接字无效。
        socket_error:自定义的套接字错误码。
        bytes_read:读入的字节数。
        bytes_move:写出的字节数。
        is_connected:是否已连接。0为未连接,否则已连接。
        is_bound:套接字是否已绑定。
        sin:本地套接字地址。
        remote_sin:远程套接字地址。
2.        MySocket类实现的功能
MySocket类所实现的功能分为以下几类。
        参数设置。用于设置与套接字相关的参数,如SetAddressFamily()、SetProtocolFamily()、SetPortNumber()等。
        套接字功能。用于初始化/关闭套接字,以及绑定连接等操作,如InitSocket()、Close()、Bind()、Connect()、Accept()、Listen()、ShutDown()等。
        基于流的I/O功能。用于TCP的读写操作,如Recv()、Send()、RemoteRecv()、RemoteSend()等。
        套接字信息数据库功能。用于获取与套接字相关的参数,如GetPeerName()、GetSockName()、GetIPAddress()等。
        套接字状态功能。用于获得当前套接字状态,如IsConnedted()、IsBound()、SetSocket()等。
        基于数据报I/O功能。用于UDP的读写操作,如RecvFrom()、SendTo()等。
        异常处理功能。用于获取或设置错误码,如GetSocketError()、SetSocketError()等。
3.        利用OOP的重载功能
为了适应不同的用途,同一系统调用被封装到不同的成员函数中,这些函数使用同一名称却又不同的参数列表,这是利用OOP的重载实现的。例如,基于TCP的读功能有四个成员函数:
        int Recv(void *buf,int bytes,int flags=0):只有当MySocket类为客户所使用时,才调用该函数。它从MySocket套接字中读数据。
        int Recv(void *buf,int bytesmint seconds,int useconds,int flags=0):与上一函数一样,但增加了超时处理功能。
        int Recv(int s,void *buf,int bytes,int flags=0):从一指定的套接字中读数据。
        int Recv(int s,void *buf,int bytesmint seconds,int useconds,int flags=0):与上一函数一样,但增加了超时处理功能。
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:39:59 | 显示全部楼层

File : mysocket.h

[code:1]
/*File : mysocket.h*/
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>

/*Define constant*/
const unsigned MysBUF_SIZE=1024;               //固定字串缓冲区长度
const unsigned MysMAX_NAME_LEN=256;            //最大名字长度
const unsigned MysRX_BUF_SIZE=4096;            //默认接收缓冲区大小
const unsigned MysTX_BUF_SIZE=4096;            //默认发送缓冲区大小
const unsigned MAXCONN=5;                      //默认最大连接数
const unsigned MysSOCKET_DEFAULT_PORT=1234;    //默认端口号

/*Define Error*/
enum MySocketError{                          //定义枚举类型MySocketError,包括所有自定义错误码
  MySOCKET_NO_ERROR=0,
  MySOCKET_INVALID_ERROR_CODE,

  //socket error codes
  MySOCKET_ADDEPT_ERROR,
  MySOCKET_BIND_ERROR,
  MySOCKET_BUFOVER_ERROR,
  MySOCKET_CONNECT_ERROR,
  MySOCKET_FILESYSTEM_ERROR,
  MySOCKET_GETOPTION_ERROR,
  MySOCKET_HOSTNAME_ERROR,
  MySOCKET_INIT_ERROR,
  MySOCKET_LISTEN_ERROR,
  MySOCKET_PEERNAME_ERROR,
  MySOCKET_PROTOCOL_ERROR,
  MySOCKET_RECEIVE_ERROR,
  MySOCKET_REQUEST_TIMEOUT,
  MySOCKET_SERVICE_ERROR,
  MySOCKET_SETOPTOPN_ERROR,
  MySOCKET_SOCKNAME_ERROR,
  MySOCKET_SOCKETTYPE_ERROR,
  MySOCKET_TRANSMIT_ERROR,
};

/*****************************************************
Class name:MySocket
Function:A wrapper class of basoc socket function.
*****************************************************/
class MySocket                      //定义MySocket类,其成员函数包括以下几类
{
protected:
  sa_family_t address_family;
  int protocol_family;
  int socket_type;
  int port_number;
  int Mysocket;
  int conn_socket;
  MySocketError socket_error;

protected:
  int bytes_read;
  int bytes_moved;
  int is_connected;
  int is_bound;

public:
  sockaddr_in sin;
  sockaddr_in remote_sin;

public:
  MySocket();
  MySocket(int st,int port,char *hostname=0);
  MySocket(sa_family_t af,int st,int pf,int port,char* hostname=0);
  virtual ~MySocket();

public:
  void SetAddressFamily(sa_family_t af) {address_family=af;}
  void SetProtocolFamily(int pf) {protocol_family=pf;}
  int GetProtocolFamily(){return protocol_family;}
  void SetSocketType(int st){socket_type=st;}
  int GetSocketType(){return socket_type;}
  void SetPortNumber(int p){port_number=p;}
  int GetBoundSocket(){return Mysocket;}
  int GetSocket(){return Mysocket;}
  int GetRemoteSocket{return conn_socket;}

public://Socket fuction
  int Socket();
  int InitSocket(int st,int port,char *hostname=0);
  int InitSocket(sa_family_t af, int st, int pf, int port ,char* hostname=0);
  void Close();
  void Close(int &s);
  void CloseSocket();
  void CloseRemoteSocket();
  int Bind();
  int Connect();
  int Accept();
  int Listen(int mac_connections=MAXCONN);
  void ShutDown(int how=0);
  void ShutDown(int &s,int how=0);
  void ShutDownSocket(int how=0);
  void ShutCownRemoteSocket(int how=0);
  int GetSockOpt(int s, int level, int optName, void *optVal, unsigned *optLen);
  int GetSockOpt(int level, int optName, void *optVal, unsigned *optLen);
  int SetSockOpt(int s, int level, int optName,const void *optVal, unsigned optLen);
  int SetSockOpt(int level, int optName,const void *optVal, unsigned optLen);

  //Stream function
  int Recv(void *buf, int bytes, int flags=0);//just for client
  int Recv(int s, void *buf, int bytes, int flags=0);
  int Recv(void *buf, int bytes,int seconds,int useconds,int flags=0);//just for client
  int Recv(int s,void *buf, int bytes,int seconds,int useconds,int flags=0);
  int Send(const void *buf, int bytes, int flags=0);//just for client
  int Send(int s,const void *buf, int bytes, int flags=0);
  int RemoteRecv(void *buf,int bytes,int seconds,int useconds, int flags=0);//just for client
  int RemoteRecv(void *buf,int bytes,int flags=0);//just for server
  int RemoteRecv(const void *buf,int bytes,int flags=0);
  void ResetRead(){bytes_read=0;}
  void ResetWrite(){bytes_moved=0;}

  //information database
  int GetPeerName(int s, sockaddr_in *sa);
  int GetPeerName();
  int GetSockName(int s, sockaddr_in *sa);
  int GetSockName();
  int GetServByName(char *name,char *protocol=0);
  int GetServByName(int port, char *protocol=0);
  servent *GetServiceInformation(char *name,char *protocol=0);
  servent *GetServiceInformation(int port, char *protocol=0);
  int GetPortNumber();
  int GetHostName(char *sbuf);
  int GetIPAddress(char *sbuf);
  int GetDomainName(char *sbuf);
  int GetBoundIPAddress(char *sbuf);
  int GetRemoteHostName(char *sbuf);
  hostent *GetHostInformation(char *hostname);
  void GetClientInfo(char *client_name,int &r_port);
  sa_family_t GetAddressFamily();
  sa_family_t GetRemoteAddressFamily();

  //Process control functions
  int ReadSelect(int s, int seconds, int useconds);
  int BytesRead(){return bytes_read;}
  int BytesMoved(){return bytes_moved;}
  int SetBytesRead(int bytes=0){return bytes_read=bytes;}
  int SetBytesMoved(int bytes=0){return bytes_moves=bytes;}
  int *GetBytesRead(){return &bytes_read;}
  int *GetBytesMoved(){return &bytes_moved;}
  int IsConnected(){return is_connected==-1;}
  int IsBound(){return is_bound==1;}
  int SetSocket(int s){return Mysocket=s;}
  int SetRemoteSocket(int s){return conn_socket=s;}
  void ReleaseSocket(){Mysocket=(int)-1;}
  void ReleaseRemoteSocket(){conn_socket=(int)-1;}

  //Datagram fuctions
  int RecvFrom(int s,sockaddr_in *sa, void *buf,int bytes,int seconds,int useconds,int flags=0);
  int RecvFrom(int s,sockaddr_in *sa, void *buf,int bytes,int flags=0);
  int SendTo(int s, sockaddr_in *sa, void *buf);
  int RecvFrom(void *buf, int bytes, int flags=0);
  int RecvFrom(void *buf, int bytes, int seconds, int useconds, int flags=0);
  int SendTo(void *buf, int bytes, int flages);

  //Exception handling functions
  MySocketError GetSocketError(){return socket_error;}
  MySocketError GetSocketError() const {return socket_error;}
  MySocketError SetSocketError(MySocketError err){
    return socket_error=err;
  }
  MysocketError ResetSocketError(){
    return socket_error=MySOCKET_NO_ERROR;
  }
  MysocketError ResetError(){
    return socket_error=MySOCKET_NO_ERROR;
  }

};
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:41:23 | 显示全部楼层

mysocket.cpp

[code:1]
/*File :mysocket.cpp*/
#include <string.h>
#include <fcnt1.h>
#include "mysocket.h"

MySocket::MySocket()           //实现MySocket的构造函数
{
  address_family=AF_INET;
  socket_type=SOCK_STREAM;
  protocol_family_IPPROTO_TCP;
  port_number=MySOCKET_SEFAULT_PORT;
  Mysocket=-1;
  conn_socket=-1;
  bytes_read=bytes_moved=0;
  is_conn_socket=0;
  is_bound=0;
  socket_error=MySOCKET_NO_ERROR;
}

MySocket::MySocket(sa_family_t af, int st, int pf,int port, char *hostname)
{
  Mysocket=-1;
  conn_socket=-1;
  bytes_read=bytes_moves=0;
  is_connected=0;
  is_bound=0;
  socket_error=MySOCKET_NO_ERROR;

  InitSocket(af,st,pf,port,hostname);
}

MySocket::MySocket(int st, int port, char*hostname)
{
  Mysocket=-1;
  conn_socket=-1;
  bytes_read=bytes_moved=0;
  is_conneted=0;
  is_bound=0;
  socket_error=MySOCKET_NO_ERROR;

  Initsocket(st, port,hostname);
}

MySocket::~MySocket()       //析构函数
{
  close();
}

int MySocket::Socket()      //产生套接字
{
  Mysocket=socket(address_family, socket_type, protocol_family);
  if(Mysocket<0)
  {
    socket_error=MySOCKET_INIT_ERROR;
    return -1;
  }

  return Mysocket;
}
  
int MySocket::InitSocket(sa_family_t af,int st,int pf,int port,char *hostname)  //初始化套接字
{

  address_family=af;
  socket_type=st;
  protoco_family=pf;
  port_number=port;

  sin.sin_family=address-family;

  if(hostname){
    hostent *hostnm=gethostbyname(hostname);
    if(hostnm==(struct hostent *) 0){
      socket_error=MySOCKET_HOSTNAME_ERROR;
      return -1;
  }
  else
    sin.sin_addr.s_addr=INADDR_ANY;
  sin.sin_port=htons(port_number);

  if(Socket()<0){
    socket_error=MySOCKET_INIT_ERROR;
    return -1;
  }

  return Mysocket;
}

int MySocket::InitSocket(int st,int port,char *hostname)
{
  address_family=AF_INET;
  port_number=port;

  if(st==SOCK_STREAM){
    socket_type=SOCK_STREAM;
    protocol_family=IPPROTO_TCP;
  }
  else if(st==SOCK_DGRAM){
    socket_type=SOCK_DGRAM;
    protocol_family=IPPROTO_UDP;
  }
  else{
    socket_error=MySOCKET_SOCKETTYPE_ERROR;
    return -1;
  }

  sin.sin_family=address_family;

  if(hostname){
    hostent *hostnm=gethostbyname(hostname);
    if(hostnm==(struct hostent *)0){
      socket_error=MySOCKET_HOSTNAME_ERROR;
      return -1;
    }

    sin.sin_addr.s_addr=*((unsigned long *)hostnm ->h_addr);
  }
  else
    sin.sin_addr.s_addr=INADDR_ANY;

  sin.sin_port=htons(port_number);

  if(Socket()<0){
    socket_error=MySOCKET_INIT_ERROR;
    return -1;
  }

  return Mysocket;
}

int MySocket::Bind()    //实现套接字的绑定功能
{
  int rv=bind(Mysocket,(struct sockaddr *)&sin, sizeof(sin));
  if(rv>=0){
    is_bound=1;
  }
  else{
    socket_error=MySOCKET_BIND_ERROR;
    is_bound=0;
  }
  return rv;
}

int MySocket::Connect()    //实现套接字的连接操作
{
  int rv=connect(Mysocket,(struct sockaddr *)&sin, sizeof(sin));
  if(rv>=0){
    is_connected=1;
  }
  else{
    socket_error=MySOCKET_CONNECT_ERROR;
    is_connected=0;
  }
  return rv;
}

int MySocket::ReadSelect(int s, int seconds, int useconds)  //实现套接字的读操作的超时设定
{
  struct timeval timeout;
  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(s,&fds);

  timeout.tv_sec=seconds;
  timeout.tv_usec=useconds;

  return select(s+1, &fds, 0, 0, &timeout);
}

int MySocket::Recv(void *buf, int bytes, int flags)      //实现套接字的读取操作
{
  return Recv(Mysocket, buf, bytes, flags);
}

int MySocket::Recv(void *buf, int bytes, int seconds, int useconds,int flags)
{
  return Recv(Mysocket, buf, bytes, seconds, useconds, flags);
}

int MySocket::Send(const void *buf, int bytes, int flags)      //实现套接字的发送操作
{
  return Send(Mysocket, buf, bytes, flags);
}

int MySocket::Recv(int s, void *buf, int bytes, int flags)       //实现套接字接受操作,用于接受指定数目的字符
{
  bytes_read=0;
  int num_read=0;
  int num_req =(int)bytes;
  char *p=(char *)buf;

  while(bytes_read<bytes){
    if((num_read=recv(s,p,num_req-bytes_read,flags))>0){
      bytes_read+=num_read;
      p+=num_read;
    }
    if(num_read<0){
      socket_error=MySOCKET_RECEIVE_ERROR;
      return -1;
    }
  }

  return bytes_read;
}

int MySocket::Recv(int s, void *buf, int bytes, int seconds, int useconds, int flags)
{
  bytes_read=0;
  int num_read=0;
  int num_req =(int)bytes;
  char *p=(char *)buf;

  while(bytes_read<bytes){
    if(!ReadSelect(s,seconds,useconds)){
      socket_error=MySOCKET_REQUEST_TIMEOUT;
      return -1;
    }
    if((num_read=recv(s,p,num_req-bytes_read,flags))>0){
      bytes_read+=num_read;
      p+=num_read;
    }
    if(num_read<0){
      socket_error=MySOCKET_RECEIVE_ERROR;
      return -1;
    }
  }

  return bytes_read;
}

int MySocket::Send(int s, const void *buf,int bytes,int flags)     //发送指定数目的字符
{
  bytes_moved=0;
  int num_moved=0;
  int num_req=(int)bytes;
  char *p=(char *)buf;

  while(bytes_moved<bytes){
    if(num_moved=send(s,p,num_req-bytes_moved,flags))>0){
      bytes_moved+=num_moved;
      p+=num_moved;
    }
    if(num_moved<0){
      socket_error=MySOCKET_TRANSMIT_ERROR;
      return -1;
    }
  }

  return bytes_moved;
}

int MySocket::RemoteRecv(void *buf,int bytes,int seconds,int useconds,int flags)    //接收指定数目的字符,用于客户端操作
{
  return Recv(conn_socket, buf, bytes, seconds, useconds, flags);
}

int MySocket::RemoteRecv(void *buf,int bytes,int flags)
{
  return Recv(conn_socket, buf, bytes, flags);
}

int MySocket::RemoteSend(const void *buf,int bytes,int flags)       //客户端数据发送
{
  return Send(conn_socket, buf, bytes, flags);
}

void MySocket::ShutDown(int how)     //实现套接字关闭操作
{
  bytes_moved=0;
  bytes_read=0;
  is_connected=0;
  is_bound=0;

  if(Mysocket!=-1) shutdown(Mysocket,how);
  if(conn_socket !=-1) shutdown(conn_socket,how);

  Mysocket=-1;
  conn_socket=-1;
}

void MySocket::ShutDown(int &s, int how)
{
  if(s!=-1) shutdown(s,how);
  s=-1;
}

void MySocket::ShutDownSocket(int how)
{
  if(Mysocket != -1) shutdown(Mysocket, how);
  Mysocket=-1;
}

void MySocket::ShutDownRemoteSocket(int how)
{
  if(conn_socket != -1) shutdown(conn_socket, how);
  conn_socket=-1;
}

void MySocket::Close()
{
  bytes_moved=0;
  bytes_read=0;
  is_connected=0;
  is_bound=0;

  if(Mysocket !=-1) close(Mysocket);
  if(conn_socket !=-1) close(conn_socket);
}

void MySocket::Close(int &s)
{
  if(s!=-1) close(s);
  s=-1;
}

void MySocket::closeSocket()//Close the server side socket
{
  if(Mysocket!=-1) close(Mysocket);
  Mysocket=-1;
}

void MySocket::CloseRemoteSocket()
{
  if(conn_socket!=-1) close(conn_socket);

  conn_socket=-1;
}

int MySocket::Listen(int max_connections)     //实现套接字侦听操作
{
  int rv=listen(Mysocket,
      max_connections);
  if(rv<0) socket_error=MySOCKET_LISTEN_ERROR;
  return rv;
}

int MySocket::Accept()                //实现套接字接收连接操作
{
  int addr_size=(int)sizeof(remote_sin);

  conn_socket=accept(Mysocket,(struct sockaddr *)&remote_sin,&addr_size);

  if(conn_socket<0)
  {
    socket_error=MySOCKET_ACCEPT_ERROR;
    return -1;
  }

  return conn_socket;
}

int MySocket::GetSockName(int s, sockaddr_in *sa)       //获得套接字的名字
{
  int namelen=(int)sizeof(sockaddr_in);
  int rv=getsockname(s,(struct sockaddr *)sa, &namelen);
  if(rv<0) socket_error=MySOCKET_SOCKET_ERROR;
  return rv;
}

int MySocket::GetSockName()
{
  return GetSockName(Mysocket, &sin);
}

int MySocket::GetPeerName(int s, sockaddr_in *sa)        //获得远程套接字的名字
{
  int namelen=(int)sizeof(sockaddr_in);
  int rv=getpeername(s, (struct sockaddr *)&sa, &namelen);
  if(rv<0) socket_error=MySOCKET_PEERNAME_ERROR;
  return rv;
}

int MySocket::GetPeerName()
{
  return GetPeerName(conn_socket, &remote_sin);
}

int MySocket::GetSockOpt(int s, int level, int optName, void *optVal, unsigned *optLen)      //获得套接字选项
{

  int rv=getsockopt(s, level, optName, optVal, (int *)optLen);
  if(rv<0) socket_error=MySOCKET_SETOPTION_ERROR;
  return rv;
}

int MySocket::GetSockOpt(int level, int optName, void *optVal, unsigned *optLen)
{
  return GetSockOpt(Mysocket, level, optName, optVal, optLen);
}

int MySocket::SetSockOpt(int s, int level, int optName, const void *optVal, unsigned *optLen)    //设置套接字选项
{

  int rv=setsockopt(s, level, optName, optVal, (int)optLen);
  if(rv<0) socket_error=MySOCKET_SETOPTION_ERROR;
  return rv;
}

int MySocket::SetSockOpt(int level, int optName, const void *optVal, unsigned optLen)
{
  return SetSockOpt(Mysocket, level, optName, optVal, optLen);
}

servent *mySocket::GetServiceInformation(char *name, char *protocol)      //获得服务信息
{
  server *sp=getservbyname(name,protocol);
  if(sp==0) return 0;

  servent *buf=new servent;
  if(!buf) return 0;
  memmove(buf, sp,sizeof(servent));
  return buf;
}

servent *MySocket::GetServiceInformation(int port,char *protocol)
{
  servent *sp=getservbyport(port,protocol);
  if(sp==0) return 0;

  servent *buf=new servent;
  if(!buf) return 0;
  memmove(buf, sp, sizeof(servent));
  return buf;
}

int MySocket::GetServByName(char *name, char *protocol)       //通过名字获得服务信息
{
  servent *sp=getservbyname(name,protocol);
  if(sp==0){
    socket_error=MySOCKET_PROTOCOL_ERROR;
    return -1;
  }
  sin.sin_port=sp->s_port;
  return 0;
}

int MySocket::GetServByPort(int port, char *protocol)       //通过端口号获得服务信息
{
  servent *sp=getservbyport(port, protocol);
  if(sp==0){
    socket_error=MySOCKET_PROTOCOL_ERROR;
    return 0;
  }
  sin.sin_port=sp->s_port;
  return 0;
}

int MySocket::GetPortNumber()                     //获得本地端口号
{
  return ntohs(sin.sin_port);
}

int MySocket::GetRemotePortNumber()               //获得远程端口号
{
  return ntohs(remote_sin.sin_port);
}

sa_family_t MySocket::GetAddressFamily()          //获得本地地址簇
{
  return sin.sin_family;
}

sa_family_t MySocket::GetRemoteAddressFamily()    //获得远程地址簇
{
  return remote_sin.sin_family;
}

hostent *MySocket::GetHostInformation(char *hostname)      //通过主机名获得主机信息
{
  in_addr hostia;
  hostent *hostinfo;
  hostia.s_addr=inet_addr(hostname);

  if(hostia.s_addr==NULL){
    hostinfo=gethostbyname(hostname);
  }
  else{
    hostinfo=gethostbyaddr((const char *)&hostia,
             sizeof(in_addr),AF_INET);
  }
  if(hostinfo==(hostent *)0){
    return 0;
  }

  hostent *buf=new hostent;
  if(!buf) return 0;
  memmove (buf, hostinfo, sizeof(hostent));
  return buf;
}

int MySocket::GetHostName(char *sbuf)                       //获得主机名
{
  if(!sbuf) sbuf=new char[MysMAX_NAME_LEN];
  int rv=gethostname(sbuf, MysMAX_NAME_LEN);
  if(rv<0) socket_error=MySOCKET_HOSTNAME_ERROR;
  return rv;
}

int MySocket::GetIPAddress(char *sbuf)                       //获得IP地址
{
  char hostname(MysMAX_NAME_LEN);
  int rv=GetHostName(hostname);
  if(rv<0) return rv;

  in_addr *ialist;
  hostent *hostinfo=GetHostInformation(hostname);
  if(!hostinfo){
    socket_error=MySOCKET_HOSTNAME_ERROR;
    return -1;
  }
  ialist=(in_addr *)hostinfo->h_addr_list[0];

  if(!sbuf)sbuf=new char[MysMAX_NAME_LEN];

  strcpy(sbuf,inet_ntoa(* ialist));
  delete hostinfo;
  return 0;
}

int MySocket::GetDomainName(char *sbuf)                       //获得域名
{
  char hostname[MysMAX_NAME_LEN];
  int rv=GetHostName(hostname);
  if(rv<0) return rv;

  hostent *hostinfo=GetHostInformation(hostname);
  if(!hostinfo){
    socket_error=MySOCKET_HOSTNAME_ERROR;
    return -1;
  }

  if(!sbuf) sbuf=new char[MysMAX_NAME_LEN];

  strcpy(sbuf,hostinfo->h_name);
  int i; int len=strlen(sbuf);
  for(i=0;i<len;i++){
    if(sbuf[1])=='.') break;
  }
  if(++i<len){
    len-=i;
    memmove(sbuf,sbuf+i,len);
    sbuf[len]=0;
  }
  delete hostinfo;
  return 0;
}

int MySocket::GetBoundIPAddress(char *sbuf)                       //获得绑定的IP地址
{
  char *s=inet_ntoa(sin.sin_addr);
  if(s==0){
    socket_error=MySOCKET_HOSTNAME_ERROR;
    return -1;
  }

  if(!sbuf) sbuf=new char[MysMAX_NAME_LEN];

  strcpy(sbuf, s);
  return 0;
}

int MySocket::GetRemoteHostName(char *sbuf)                       //获得远程主机名
{
  char *s=inet_ntoa(remote_sin.sin_addr);
  if(s==0){
    socket_error=MySOCKET_HOSTNAME_ERROR;
    return -1;
  }

  if(!sbuf) sbuf=new char[MysMAX_NAME_LEN];

  strcpy(sbuf, s);
  return 0;
}

void MySocket::GetClientInfo(char *client_name,int &r_port)                   //获得客户信息
{
  int rv=GetRemoteHostName(client_name);
  if(rv<0){
    char *unc="UNKNOWN";
    for(unsigned i=0;i<MysMAX_NAME_LEN;i++) client_name[i]='\0';
    strcpy(client_name,unc);
  }
  r_port=GetRemotePortNumber();
}

int MySocket::RecvFrom(void *buf, int bytes, int flags)                       //数据报接收操作
{
  return RecvFrom(Mysocket, &remote_sin, buf, bytes, flags);
}

int MySocket::SendTo(void *buf, int bytes, int flags)                         //数据报发送操作
{
  return SendTo(Mysocket, &sin, buf, bytes, flags);
}

int MySocket::RecvFrom(int s, sockaddr_in *sa, void *buf,
                       int bytes, int seconds, int useconds, int flags)       //数据报接收操作并具有超时返回功能
{
  int addr_size=(int)sizeof(sockaddr_in);
  bytes_read=0;
  int num_read=0;
  int num_req=(int)bytes;
  char *p=(char *)buf;

  while(bytes_read<bytes){
    if(!ReadSelect(s, seconds, useconds)){
      socket_error=MySOCKET_REQUEST_TIMEOUT;
      return -1;
    }
    if((num_read=recvfrom( s, p, num_req-bytes_read, flags, (struct sockaddr *)sa, &addr_size))>0){
      bytes_read+=num_read;
      p+=num_read;
    }
    if(num_read<0){
      socket_error=MySOCKET_RECEIVE_ERROR;
      return -1;
    }
  }
  return bytes_read;
}

int MySocket::RecvFrom(int s, sockaddr_in *sa, void *buf, int bytes, int flags)  //接收指定数目的字符
{
  int addr_size=(int)sizeof(sockaddr_in);
  bytes_read=0;
  int num_read=0;
  int num_req=(int)bytes;
  char *p=(char *)buf;

  while(bytes_read<bytes){
    if((num_read=recvfrom( s, p, num_req-bytes_read, flags, (struct sockaddr *)sa, &addr_size))>0){
      bytes_read+=num_read;
      p+=num_read;
    }
    if(num_read<0){
      socket_error=MySOCKET_RECEIVE_ERROR;
      return -1;
    }
  }
  return bytes_read;
}

int MySocket::SendTo(int s, sockaddr_in *sa, void *buf, int bytes, int flags)    //发送指定数目的字符
{
  int addr_size=(int)sizeof(sockaddr_in);
  bytes_moved=0;
  int num_moved=0;
  int num_req=(int)bytes;
  char *p=(char *)buf;

  while(bytes_moves<bytes){
    if((num_moved=sendto( s, p, num_req-bytes_read, flags, (const struct sockaddr *)sa, addr_size))>0){
      bytes_moved+=num_moved;
      p+=num_moved;
    }
    if(num_moved<0){
      socket_error=MySOCKET_TRANSMIT_ERROR;
      return -1;
    }
  }
  return bytes_moved;
}[/code:1]
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:47:10 | 显示全部楼层

我再帖::mysync.h mysync.cpp

[code:1]
/*************************************************
class name :MyMutex
Function:support mutex
*************************************************/
class MyMutex
{
  pthread_mutex_t a_mutex;           //存放互斥锁
  int error;                         //存放错误码

public:
  MyMutex();
  ~MyMutex();

  int Lock(){error=pthread_mutex_lock(&a_mutex);return error;}      //加锁
  int Trylock(){error=pthread_mutex_trylock(&a_mutex);return error;}//试锁
  int Unlock(){error=pthread_mutex_unlock(&a_mutex);return error;}  //解锁
  int Error(){return error;}                                        //错误
};
/*******************************************************
class name:MyCondition
Function:support MyCondition variable
*******************************************************/

class MyCondition
{
  pthread_mutex_t a_mutex;      //定义MyCondition类的成员变量 ----互斥锁
  pthread_cond_t got_request;   //条件变量
  int error;

public:
  MyCondition();
  ~MyCondition();

  int wait(int second=0);//wait until signal by other thread   //声明MyCondition的成员函数
  int wake();            //wake a thread waiting fir this condition
  int wakeAll();         //wake all threads waiting for this condition
  int Error() {return error;}
};
[/code:1]
[code:1]
/*File :mysync.cpp*/
#include <iostream.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include "MySync.h"

MyMutex::MyMutex()            //构造函数,初始化一个互斥锁
{
error=pthread_mutex_init(&a_mutex,NULL);
}

MyMutex::~MyMutex()           //析构函数,撤销互斥锁
{
error=pthread_mutex_destroy(&a_mutex);
}

MyCondition::MyCondition()    //构造函数,初始化一个互斥锁及条件变量
{
error=pthread_cond_init(&got_request,NULL);
error+=pthread_mutex_init(&a_mutex,NULL);
}

MyCondition::~MyCondition()  //析构函数,撤销互斥锁及条件变量,如果还有线程守护该条件变量,则等待直至该线程退出.
{error=pthread_mutex_destroy(&a_mutex);
int rc=pthread_con_destrou(&got_request);
/*some thread is still waiting on this scondition variable*/
while(rc==EBUSY){
  sleep(1);
  }
error=error+rc;
}

int MyCondition::wait(int second=0)  //令线程守候在MyCondition对象的条件变量got_request上直至被唤醒或超时
{
struct timewal now;      /*time when we started waiting*/
struct timespec timeout; /*timeout value for the wait function */
int done;                /*are we done waiting?*/
/*first,lock the mutex*/
int rc=pthread_mutex_lock(&a_mutex);    //加锁
if(rc){/*an error has occured*/
  perror("pthread_mutex_lock");
  pthread_exit(NULL);
  }

if(second){/*get current time*/         //设置定时,并守候
  gettimeofday(&now,NULL);
  /*prepare timeout value*/
  timeout.tv_sec=now.tv_sec+second;
  timeout.tv_nsec=now.tv_usec*1000;/*timeval uses microseconds.*/
  /*timespec uses nanoseconds.*/
  /*1 nanosecond=1000 microseconds.*/

  error=pthread_cond_timedwait(&got_request,&a_mutex,&timeout);
}else error=pthread_cond_wait(&got_request,&a_mutex);

/*finally,unlock the mutex*/
pthread_mutex_unlock(&a_mutex);         //解锁

switch(error){                          //错误处理
/*we were awakened due to the cond. variable being signaled*/
case 0:
      /*the mutex was now locked again by pthread_cond_timedwait.*/
      /*do your stuff here...*/

case ETIMEDOUT:/*out time is up*/

default:       /*some error occurred(e.g. we got a Linux signal)*/
    return 2;  /*break this switch,but re-do the while loop.    */
}
}

int MyCondition::wake()                  //唤醒一个线程
{
error=pthread_cond_signal(&got_request);
return error;
}

int MyCondition:wakeAll()                //唤醒所以守候线程
{
error =pthread_cond_broadcast(&got_request);
return error;
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:50:33 | 显示全部楼层

tcpservthr

[code:1]
/**********************************************
class name : TcpServThr
Function : support TCP Server with multuthread
**********************************************/
class TcpServThr :public MySocket
{
int mac_connedtions;                  //存放最大的连接数量
vector<MyThread*>* ThrSet;            //指向线程队列的指针,该指针存放当前所有线程

public:
  TcpServThr();                       //构造函数
  TcpServThr(int port, char *hoxtname=NULL);
  TcpServThr(int port, int maxconn,char *hostname=NULL);
  wirtual ~TcpServThr();              //析构函数

  void SetMaxConn(int num){max_connection=num;}      //设置最大连接数
  int GetMaxConn(){return max_connections;}          //获得最大连接数
  int Init();                                        //初始化TCP多线程服务器,产生监听套接字并绑定
  int Run();                                         //运行TCP,建立连接
  
  virtual void DealRecv(MyThread* thread);           //虚函数,用于处理接收过程,允许子函数重载以满足不同需要
  virtual void DealSend(MyThread* thread);           //虚函数,用于处理发送过程,允许子函数重载以满足不同需要

protected:
  int CreateThr(MuThread** Rthread, MyThread** Wthread);  //产生收/发线程
  void AddThread(MyThread* thread);                       //将线程加入线程队列
  void DelThread(MyThread* thread);                       //将线程从线程队列中删除
  int WaitallThr();                    //线程结束时的同步,即主线程退出前,应等待所有其它线程退出

class Receiver:public MyThread         //类定义,产生接收线程
{
public;
int socket;
TcpServThr* server;

Receiver(int connsocker,TcpServThr* serv){
  socket=connsocket;
  server=serv;
  }
void run(){server->DealRecv(this);}
};

class Sender:public MyThread           //类定义,产生发送线程
{
public:
  int socket;
  TcpServThr* server;

Sender(int connsocker, TcpServThr* serv){
  socket=connsocket;
  server=serv;
  }
void run(){server->DealSend(this);}
};
[/code:1]
[code:1]
/*File :tcpservthr.cpp*/
#include <stdio.h>
#include <vector.h>
#include "pthread.h"
#include "Mysocket.h"
#include "MyThread.h"
#include "TcpServThr.h"

TcpServThr::TcpServThr()         //构造函数,设置与TCP套接字相关参数及产生线程队列
{
max_connections=MAXCONN;
ThrSet=new vector<MyThread *>();
}

TcpServThr::TcpServThr(int port , char * hostname):
    MySocket(AF_INET,SOCK_STREAM,0,port,hostname)
{
max_connections=MAXCONN;
ThrSet=new vector<MyThread *>();
}

TcpServThr::TcpServThr(int port,int maxconn,char * hostname):
    MySocket(AF_INET,SOCK_STREAM,0,port,hostname)
{
max_connections=MAXCONN;
ThrSet=new vector<MyThread *>();
}

TcpServThr::~TcpServThr()       //析构函数
{
/*Wait until all threads exits*///等待所有线程退出
WaitAllThr();
/*free all memory of threads*/
vector<MyThread *>::iterator it =ThrSet->begin();  //扫描线程队列
while (it !=ThrSet->end()){
  MyThread *thr=(MyThread *)(*it);
  delete thr;                                      //删除所有线程对象
  it++;
  }

delete ThrSet;                                     //删除线程队列
}

int TcpServThr::Init()                             //Tcp套接字的绑定和监听
{
int opt = SO_REUSEADDR;
setsockopt(Mysocket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

if(Bind()==-1) return socket_error;
if(Listen(max_connections)==-1) return socket_error;
return 0;
}

int TcpServThr::Run()      //反复接收客户连接,一旦连接建立,则产生收/发线程,并将它们加入线程队列,再运行它们
{
while(Accept()!=-1){
  /*Create new thread*/
  MyThread *Rthread, *Wthread;
  if(CreateThr(&Rthread,&Wthread)==-1) return -1;
  AddThread(Rthread);
  AddThread(Wthread);
  if(Rthread->Start()) return -1;
  if(Wthread->Start()) return -1;
  }
return -1;
}

int TcpServThr::CreateThr(MyThread** Rthread,MyThread** Wthread)  //产生收/发线程对象
{
printf("Accept Conn\n");
*Rthread= new Receiver(conn_socket,this);
*Wthread= new Sender(conn_socket,this);
return 0;
}

void TcpServThr::DealRecv(MyThread* thread)    //默认的接收处理,无实际意义,在具体应用中将被重载
{
printf("Receiver is running!\n");
}

void TcpServThr::DealSend(MyThread* Thread)    //默认的发送处理,无实际意义,在具体应用中将被重载
{
printf("Sender is running!\n");
}

void TcpServThr::AddThread(MyThread* Thread)    //将线程对象加入线程队列
{
if(thread==NULL) return;
ThrSet->push_back(thread);
}

void TcpServThr::DelThread(MyThread* thread)     //将指定线程对象从线程队列中删除
{
vector<MyThread*>::iterator it=ThrSet->begin();
while(it !=ThrSet->end()){
if(((MyThread*)*it)==thread){
  ThrSet->erase(it);
  break;
  }
it++;
}
}

int TcpServThr::WaitAllThr()   //等待线程队列中所有线程退出
{
vector<MyThread*>::iterator it=ThrSet->begin();
  while(it !=ThrSet->end()){              //扫描线程队列,等待每个线程退出
    MyThread* thr==(MyThread*)(*it);
    pthread_join(thr->getId(),NULL);
    it++;
  }
return 0;
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:52:09 | 显示全部楼层

我还贴~~

[code:1]
/********************************************
class name :TcpCliThr
Function: support TCP client with multithread
********************************************/
class TcpCliThr :public MySocket
{
vector<MyThread*>* ThrSet;         //存放线程队列

public:
  TcpCliThr();                     //构造函数
  TcpCliThr(int port ,char *server);
  virtual ~TcpCliThr();            //析构函数,虚函数,以便子类被撤销时自动调用该函数,完成相应的清理工作

  int ConnectServ();               //与服务器连接
  virtual void DealRecv(MyThread* thread);       //虚函数,用于处理接收过程,允许子函数重载以满足不同需要
  virtual void dealRecv(MyThread* thread);       //虚函数,用于处理发送过程,允许子函数重载以满足不同需要

protected:
  int CreateThr(MyThread** Rthread,MyThread** Wthread);   //产生收/发线程
  void AddThread(MyThread* thread);                       //将线程加入线程队列
  void DelThread(MyThread* thread);                       //将线程从线程队列中删除
  int WaitAllThr();                   //线程结束时的同步,即主线程退出前,应等待所有其它线程退出

  class Receiver:public MyThread         //类定义,产生接收线程
  {
  public:
    int socket;
    TcpCliThr* server;

    Receiver(int connsocket, TcpCliThr* serv){
      socket=connsocket;
      server=serv;
    }
    void run(){server->DealRecv(this);}
  };

  class Sender :public MyThread           //类定义,产生发送线程
  {
  public:
    int socket;
    TcpCliThr* server;

    Sender(int connsocket,TcpCliThr* serv){
      socket=connsocket;
      server=serv;
    }
    void run(){server->DealSend(this);}
  };
};
[/code:1]
[code:1]
/*File :tcpclithr.cpp*/
#include <stdio.h>
#include <vector.h>
#include "pthread.h"
#include "Mysocket.h"
#include "MyThread.h"
#include "TcpCliThr.h"

TcpCliThr::TcpCliThr()        //构造函数,设置与TCP套接字相关参数及产生线程队列
{
ThrSet=new vector<MyThread *>();
}

TcpCliThr::TcpCliThr(int port ,char * server):
    MySocket(AF_INET,SOCK_STREAM,0,port,hostname)
{
ThrSet=new vector<MyThread *>();
}

TcpCliThr::~TcpCliThr()       //析构函数
{
/*Wait until all threads exits*///等待所有线程退出
WaitAllThr();
/*free all memory of threads*/
vector<MyThread *>::iterator it =ThrSet->begin(); //扫描线程队列
while (it !=ThrSet->end()){
  MyThread *thr=(MyThread *)(*it);
  delete thr;                                     //删除所有线程对象
  it++;
  }

delete ThrSet;                                     //删除线程队列
}

int TcpCliThr::ConnectServ()        //一旦连接建立,则产生收/发线程,将它们加入线程队列并运行
{
  if(Connect()==-1) return -1;
  /*Create new thread*/
  MyThread *Rthread, *Wthread;
  if(CreateThr(&Rthread,&Wthread)==-1) return -1;
  AddThread(Rthread);
  AddThread(Wthread);
  if(Rthread->Start()) return -1;
  if(Wthread->Start()) return -1;
  return 0;
}

int TcpCliThr::CreateThr(MyThread** Rthread,MyThread** Wthread)
{
  printf("Accept Conn\n");
  *Rthread= new Receiver(Mysocket,this);
  *Wthread= new Sender(Mysocket,this);
  return 0;
}

void TcpCliThr::DealRecv(MyThread* thread)    //默认的接收处理,无实际意义,在具体应用中将被重载
{
  printf("Receiver is running!\n");
}

void TcpCliThr::DealSend(MyThread* Thread)    //默认的发送处理,无实际意义,在具体应用中将被重载
{
  printf("Sender is running!\n");
}

void TcpCliThr::AddThread(MyThread* Thread)    //将线程对象加入线程队列
{
  if(thread==NULL) return;
  ThrSet->push_back(thread);
}

void TcpCliThr::DelThread(MyThread* thread)     //将指定线程对象从线程队列中删除
{
vector<MyThread*>::iterator it=ThrSet->begin();
while(it !=ThrSet->end()){
if(((MyThread*)*it)==thread){
  ThrSet->erase(it);
  break;
  }
it++;
}
}

int TcpCliThr::WaitAllThr()   //等待线程队列中所有线程退出
{
vector<MyThread*>::iterator it=ThrSet->begin();
  while(it !=ThrSet->end()){              //扫描线程队列,等待每个线程退出
    MyThread* thr==(MyThread*)(*it);
    pthread_join(thr->getId(),NULL);
    it++;
  }
return 0;
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2003-10-28 17:58:44 | 显示全部楼层

好累啊~mythread

[code:1]
/*****************************************************************
class name : Thread_interface
function:It is base class of all threads. used by class Mythead.
功能:实现多线程
*****************************************************************/

class Thread_interface               //定义MyThread的基类Thread_interface,它仅包含一个虚函数run()
{
public:
virtual void run(){}
};

/************************************************
class name : MyThread
function:Create thread and run it.
************************************************/

class MyThead : public Thread_interface
{
Thread_interface* worker;           //定义指向Thread_interface的指针。所指的对象是线程将要执行的实体
int error;
pthread_t id;                       //定义id,用于存放线程ID

static  void * run(void *);         //声明静态函数run(),用于产生线程

public:
MyThead(Thread_interface& w);       //声明MyThread类的构造函数
MyThead(){worker=this;}

int Start();                        //成员函数
void Exit(void *value_ptr) {::pthread_exit(value_ptr);}
int Join(pthread_t thread,void **value_ptr)
    {error =::pthread_join(thread,value_ptr); return error;}
int Cancel(pthread_t thread_thread)
    {error =::pthread_cancel(target_thread); return error;}
int Detach() {error = ::pthread_detach(id); return error;}
int Detach()(pthread_t thread)
    {error =::pthread_detach(thread); return error;}
pthread_t getId() {return id;}
int Error(){return id;}
};
[/code:1]
[code:1]
/* File : mythread.cpp */
#include <iostream.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include "mythread.h"

MyThread::MyThread(Thread_interface& w) //实现构造函数。将一个Thread_interface的对象附给变量worker。默认将自身(this)赋给它
{
worker =&w;
error =0;
}

void* MyThread::run(void * w)           //执行worker对象的run()函数
{
((Thread_interface * )w)->run();
}

int MyThread::Start()                   //通过系统调用pthread_create()产生线程
{
error=pthread_create(&id,NULL,run,(void *)worker);
return error;
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2003-10-28 18:04:09 | 显示全部楼层
还有客户端和服务器的主函数,我还没有完全搞好,过两天再发上来
回复

使用道具 举报

发表于 2003-10-28 23:20:47 | 显示全部楼层
汗~~~~~~~~这么多~~
我现在还一行代码都没写呢~~     
回复

使用道具 举报

 楼主| 发表于 2003-10-30 20:40:46 | 显示全部楼层
呵呵,没事的时候就写写啦,好像有很多bug,希望大家帮忙找错啊~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-13 04:08 , Processed in 0.048945 second(s), 17 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表