« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
|
公告 |
本站技术贴除标明为“原创”的之外,其余均为网上转载,文中我会尽量保留原作者姓名,若有侵权请与我联系,我将第一时间做出修改。谢谢!
——既瑜 |
统计 |
blog名称:★既瑜★ 日志总数:183 评论数量:636 留言数量:-25 访问次数:1406073 建立时间:2005年3月12日 |
OICQ:215768265
njucs2001@hotmail.com
erichoo1982@gmail.com |
|
W3CHINA Blog首页 管理页面 写新日志 退出
[【技术文档】]socket_一个简单应用_源代码 |
socket_一个简单应用_源代码
代码文件有: outer.cpp outer.h socket.cpp socket.h sockmsg.cpp sockmsg.h linent.cpp service.cpp
outer.h:=======
#ifndef _OUTER_H_#define _OUTER_H_
// 数据类型定义typedef unsigned char byte;
// 常量定义// portconst int PORT = 52309;// 一个message的最大长度const int MAX_MESSAGE_LEN = 512;
const int BACKLOG = 10;
const int CLOSE_TRY_TIMES = 10;
/* message types */// get file listconst int GET_FILE_LIST = 1;// get dir listconst int GET_DIR_LIST = 2;// copy fileconst int COPY_FILE = 3;// close socketconst int CLOSE_SOCKET = 4;
/* patameter types*/// const int TAG_DIR = 21;
const int FILE_NAME = 11;
const int TAG_FILE = 12;
const int FILE_TEXT = 13;
// function
void hexdump(byte *data, int len);
#endif
outer.cpp:==========
#include <iostream>#include "outer.h"
void hexdump(byte *data, int len) { int rows = len/16 + 1;
for (int i=0; i<rows; i++) { if (i*16 >= len) break; int j; printf("%04x: ", rows << 4); for (j=0; (j<16)&&(i*16+j<len); j++) { printf("%02x ", data[i*16+j]); if (j == 7) printf("- "); } printf("| "); for (j=0; (j<16)&&(i*16+j<len); j++) { if (isprint(data[i*16+j])) printf("%c", data[i*16+j]); else printf("."); } printf("\n"); }}
socket.h:=========/** * $Id: Socket.h,v 1.3 2005/04/06 07:16:14 guest Exp $ */
#include <string>#include "outer.h"
#ifndef __SOCKET_H__#define __SOCKET_H__
using std::string;
class Socket {public:
/** * Creates an unconnected socket, with the system-default * type of SocketImpl. */ Socket();
/** * Creates a stream socket and connects it to the specified * port number on the named host. */ Socket(string host, int port);
/** * Destructor */ virtual ~Socket();
/** * Creates an unconnected socket, with the system-default * type of SocketImpl. */ bool setup();
/** * Closes this socket. */ void close(); /** * Closes this socket. */ void close(int fd);
/** * Connects this socket to the server. */ bool connect(string host, int port);
/** * Listen witch this socket. */ bool listen();
/** * */ int accept();
/** * Returns the address to which the socket is connected. */ string getInetAddress();
/** * Gets the local address to which the socket is bound. */ string getLocalAddress();
/** * Returns the local port to which this socket is bound. */ int getLocalPort();
/** * Returns the remote port to which this socket is connected. */ int getPort();
/** * Returns the closed state of the socket. */ bool isClosed();
/** * Returns the connection state of the socket. */ bool isConnected();
/** * Receives a message from this socket. */ int recv(byte *buf, int len);
/** * Receives a message from this socket. */ int recv(int new_fd, byte *buf, int len);
/** * Sends a message through this socket. */ int send(const byte *msg, int len);
/** * Sends a message through this socket. */ int send(int new_fd, const byte *msg, int len);
private: int _fd; bool _connected; bool _closed;};
#endif
socket.cpp:===========/** * $Id: Socket.cpp,v 1.5 2005/04/06 07:16:14 guest Exp $ */
#include <errno.h>#include <stdio.h>#include <winsock2.h>
#include "Socket.h"#include "outer.h"
/** * Creates an unconnected socket, with the system-default * type of SocketImpl. */Socket::Socket() {
setup();
_closed = false;}
/** * Creates a stream socket and connects it to the specified * port number on the named host. */Socket::Socket(string host, int port) { setup(); connect(host, port);}
/** * Creates an unconnected socket, with the system-default * type of SocketImpl. */bool Socket::setup() {
WSADATA wsd; _fd = WSAStartup(MAKEWORD(2,2), &wsd); if(_fd) { printf("WSAStartup function err!\n"); return false; } _connected = false; _closed = true; printf("Socket: WSAStartup success execute.\n");
_fd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (_fd == -1) { printf(strerror(errno)); return false; } printf("Socket: socket success execute.\n"); return true;}
/** * Destructor */Socket::~Socket() { close();}
/** * Closes this socket. */void Socket::close() { if (!isClosed()) { if (_connected) { printf("Socket: Close connection to \"%s:%d\"\n", getInetAddress().c_str(), getPort()); }
int trytimes = 0; while(::closesocket(_fd) && trytimes < CLOSE_TRY_TIMES) trytimes++; if(trytimes == 10) { printf("Cannot close socket!\n"); } else { _closed = true; } }}
/** * Closes this socket. */void Socket::close(int fd) { if (!isClosed()) { if (_connected) { printf("Socket: Close connection to \"%s:%d\"\n", getInetAddress().c_str(), getPort()); }
int trytimes = 0; while(::closesocket(fd) && trytimes < CLOSE_TRY_TIMES) trytimes++; if(trytimes == 10) { printf("Cannot close socket!\n"); } else { _closed = true; } }}
/** * Connects this socket to the server. */bool Socket::connect(string host, int port) { struct hostent *_h = gethostbyname(host.c_str()); if (_h == 0) { printf(strerror(h_errno)); return false; }
struct in_addr *_addr = (struct in_addr *)_h->h_addr; struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr = *_addr; sin.sin_port = htons(port);
if (::connect(_fd, (sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) { printf(strerror(errno)); return false; }
printf("Socket: Establish the connection to \"%s:%d\"\n", getInetAddress().c_str(), getPort());
_connected = true; return true;}
/** * Listen witch this socket. */bool Socket::listen(){ struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(PORT); my_addr.sin_addr.s_addr = INADDR_ANY; if(::bind(_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == SOCKET_ERROR) { printf(strerror(errno)); return false; } else printf("bind ok!\n");
if(::listen(_fd, BACKLOG) == SOCKET_ERROR) { printf(strerror(errno)); return false; } else printf("listen ok!\n");
return true;}
/** * */int Socket::accept(){ int new_fd; struct sockaddr_in their_addr; int sin_size = sizeof(their_addr); printf("accepting... \n");
new_fd = ::accept(_fd, (struct sockaddr *)&their_addr, &sin_size); return new_fd == SOCKET_ERROR ? -1:new_fd;}
/** * Returns the address to which the socket is connected. */string Socket::getInetAddress() { struct sockaddr_in sin; //socklen_t socklen = sizeof(sin); int socklen = sizeof(sin); if (getpeername(_fd, (struct sockaddr *)&sin, &socklen) == -1) { printf(strerror(errno)); return NULL; }
return inet_ntoa(sin.sin_addr);}
/** * Gets the local address to which the socket is bound. */string Socket::getLocalAddress() { struct sockaddr_in sin; //socklen_t socklen = sizeof(sin); int socklen = sizeof(sin); if (getsockname(_fd, (struct sockaddr *)&sin, &socklen) == -1) { printf(strerror(errno)); return NULL; }
return inet_ntoa(sin.sin_addr);}
/** * Returns the local port to which this socket is bound. */int Socket::getLocalPort() { struct sockaddr_in sin; //socklen_t socklen = sizeof(sin); int socklen = sizeof(sin); if (getsockname(_fd, (struct sockaddr *)&sin, &socklen) == -1) { printf(strerror(errno)); return -1; }
return ntohs(sin.sin_port);}
/** * Returns the remote port to which this socket is connected. */int Socket::getPort() { struct sockaddr_in sin; //socklen_t socklen = sizeof(sin); int socklen = sizeof(sin); if (getpeername(_fd, (struct sockaddr *)&sin, &socklen) == -1) { printf(strerror(errno)); return NULL; }
return ntohs(sin.sin_port);}
/** * Returns the closed state of the socket. */bool Socket::isClosed() { return _closed;}
/** * Returns the connection state of the socket. */bool Socket::isConnected() { return _connected;}
/** * Receives a message from this socket. */int Socket::recv(int new_fd, byte *buf, int len){ int nb = ::recv(new_fd, (char *)buf, len, 0); if (nb == -1) { printf("Error! recv.\n"); }
return nb;}
/** * Receives a message from this socket. */int Socket::recv(byte *buf, int len) { return recv(_fd, buf, len);}
/** * Sends a message through this socket. */int Socket::send(const byte *msg, int len) { return send(_fd, msg, len);}
/** * Sends a message through this socket. */int Socket::send(int new_fd, const byte *msg, int len){ int nb = ::send(new_fd, (char *)msg, len, 0); if (nb == -1) { //throw SocketException(strerror(errno)); printf("Error! send.\n"); }
return nb;}
sockmsg.h==========
//////////////////////////////////////////////////////////////////////// A message object.//// filename:SockMsg.h// struct:// Message// +- Protocol Version 1 byte// +- Message type 2 bytes// +- Message Length 2 bytes// for ()// +- Patameter type 2 bytes// +- Patameter tag 1 bytes// +- Patameter index 2 bytes// +- Patameter data length 2 bytes// +- Patameter data var////////////////////////////////////////////////////////////////////////
#if !defined(_SOCKMSG_H_)#define _SOCKMSG_H_
#include "outer.h"
class MsgPatameter{public: MsgPatameter(byte *data, int len) { _data = new byte[len]; memcpy(_data, data, len); }
~MsgPatameter(){delete[] _data;}
inline int getType() const {return _data[0] << 8 | _data[1];} inline int getTag() const {return _data[2];} inline int getIndex() const {return _data[3] << 8 | _data[4];} inline int getLen() const {return _data[5] << 8 | _data[6];}
byte *getData() const {return _data+7;}private: byte *_data;};
class SockMsg {public: /** * */ SockMsg(void);
/** * */ virtual ~SockMsg(void);
public: /** * Returns the version of the protocol used * by this message object. */ int getProtocolVersion(void) const; /** * Returns the message length. */ int getMessageLength(void) const;
/** * Returns the message length. */ int Length(void) const;
/** * Returns the type of this message object. */ int getMessageType(void) const;
/** * Sets the version of the protocol used. */ void setProtocolVersion(const int &version);
/** * Sets the type of this message object. */ void setMessageType(const int &type);
/** * Sets a patameter info in the message. */ void setPatameter(int type, char tag, int index, int len, const byte *data);
/** * Sets a patameter info in the message. */ void setPatameter(int type, int len, const byte *data);
/** * Sets a patameter info in the message. */ void setPatameter(int type);
/** * Clear patameters from in the message. */ void clearPatameter(void);
/** * Gets data of the message. */ byte *getData(void);
/** * */ MsgPatameter * getPatameter(const int &index) const;
/** * Print datas of this message object. */ void toString(void) const;
private: /** * Sets the message_length field. */ void setMessageLength(const int &length);
private: byte *_data;
// MsgPatameter
};
#endif // !defined(_SOCKMSG_H_)
sockmsg.cpp:============// SockMsg.cpp: implementation of the SockMsg class.////////////////////////////////////////////////////////////////////////
#include <iostream>#include "SockMsg.h"
//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////
SockMsg::SockMsg(void){ _data = new byte[MAX_MESSAGE_LEN];
memset(_data, 0, MAX_MESSAGE_LEN);
setProtocolVersion(1); setMessageType(0); setMessageLength(0);}
SockMsg::~SockMsg(void){ delete[] _data;}
/** * Returns the version of the protocol used * by this _message object. */int SockMsg::getProtocolVersion(void) const { return _data[0];}
/** * Returns the _message_length field. */int SockMsg::getMessageLength(void) const { return (_data[3] << 8) | _data[4];}
/** * Returns the message length. */int SockMsg::Length(void) const { return getMessageLength() + 5;}
/** * Returns the type of this message object. */int SockMsg::getMessageType(void) const { return (_data[1] << 8) | _data[2];}
/** * Sets the version of the protocol used. */void SockMsg::setProtocolVersion(const int &version) { _data[0] = version;}
/** * Sets the message length. */void SockMsg::setMessageLength(const int &length) { _data[3] = length >> 8; _data[4] = length;}
/** * Sets the type of this message object. */void SockMsg::setMessageType(const int &type) { _data[1] = type >> 8; _data[2] = type;}
/** * Sets a patameter info in the message. */void SockMsg::setPatameter(int type, int len, const byte *data) { setPatameter(type, 1, 0, len, data);}
/** * Sets a patameter info in the message. */void SockMsg::setPatameter(int type) { setPatameter(type, 1, 0, 0, NULL);}
/** * Sets a patameter info in the message. */void SockMsg::setPatameter(int type, char tag, int index, int len, const byte *data) { int len_ = getMessageLength() + 5;
_data[len_] = type >> 8; _data[len_ + 1] = type;
_data[len_ + 2] = tag;
_data[len_ + 3] = index >> 8; _data[len_ + 4] = index;
_data[len_ + 5] = len >> 8; _data[len_ + 6] = len;
if (data) memcpy(&_data[len_ + 7], data, len);
setMessageLength(len_ + len + 2);}
/** * Gets data of the message. */byte *SockMsg::getData(void) { return _data;}
/** * Clear patameters from in the message. */void SockMsg::clearPatameter(void) { setMessageLength(0);}
/** * */MsgPatameter *SockMsg::getPatameter(const int &index) const{ int patameters_ = 5; int len_ = getMessageLength(); int index_ = 0, patlen_;
while (len_ - patameters_ >0) { patlen_ = _data[patameters_ + 5] << 8 | _data[patameters_ + 6];
if (index_ == index) { MsgPatameter *patameter = new MsgPatameter(_data + patameters_, patlen_
+ 7); return patameter; } patameters_ += patlen_ + 7; index_++; } return NULL;}
/** * Print datas of this message object. */void SockMsg::toString(void) const { int patameters_ = 5; int len_ = getMessageLength();
printf("Message info :\n"); printf(" message protocol : %d\n", getProtocolVersion()); printf(" message type : %d\n", getMessageType()); printf(" message length : %d\n", getMessageLength()); printf(" message patameter :\n");
MsgPatameter *p_pata = NULL; for (int i=0; ; i++) { p_pata = getPatameter(i); if (!p_pata) break;
printf(" patameter type : %d\n", p_pata->getType()); printf(" patameter tag : %d\n", p_pata->getTag()); printf(" patameter index : %d\n", p_pata->getIndex()); printf(" patameter data len : %d\n", p_pata->getLen());
hexdump(p_pata->getData(), p_pata->getLen());
delete p_pata; p_pata = NULL; }}
client.cpp==========
#include <stdio.h>#include <Socket.h>#include <SockMsg.h>#include <string.h>#include <iostream>
using std::cin;
int main(int argc, char **argv){ printf("socket of client is run ...\n");
Socket s; SockMsg msg;
if(!s.connect("dezhi", PORT)) { printf("Not service!\n"); return 0; }
while (1) { printf("select opration. f(show file list), c(copy file), q(exit).\n"); char m; cin >> m; if (m == 'q') break;
if (m == 'f') { printf("select dir :"); char *dir = new char[64]; cin >> dir; msg.setMessageType(GET_FILE_LIST); msg.setPatameter(TAG_DIR, strlen(dir), (byte *)dir); } else if (m == 'c') { printf("select file : "); char *file = new char[64]; cin >> file; msg.setMessageType(COPY_FILE); msg.setPatameter(TAG_FILE, strlen(file)+1, (byte *)file); } else { printf("No operation !\n"); continue; }
s.send(msg.getData(), msg.Length()); s.recv(msg.getData(), 512); msg.toString(); }
msg.clearPatameter(); msg.setMessageType(CLOSE_SOCKET); s.send(msg.getData(), msg.Length()); s.close(); return 0;}
service.cpp:============#include <stdio.h>#include <Socket.h>#include <SockMsg.h>#include <string.h>#include <iostream>
int main(int argc, char **argv){ printf("socket of service is run ...\n");
Socket s; s.listen(); SockMsg msg;
while (1) { int new_fd = s.accept();
while (s.recv(new_fd, msg.getData(), 512) != -1) { msg.toString(); if (msg.getMessageType() == CLOSE_SOCKET) break; MsgPatameter *p_pata = msg.getPatameter(0); if (msg.getMessageType() == GET_FILE_LIST) { if (p_pata->getType() == TAG_DIR) { char *dir = (char *)p_pata->getData();
getfilelist(dir); } msg.clearPatameter();
c_file *cf = _v.begin(); for (; cf < _v.end(); cf++) { char *va = cf->getdata(); printf("va len = %d\n", strlen(va)); msg.setPatameter(FILE_NAME, strlen(va), (byte *)va); } } else if (msg.getMessageType() == COPY_FILE) { if (p_pata->getType() == TAG_FILE) { int len = p_pata->getLen(); char *file = (char *)p_pata->getData(); msg.clearPatameter(); FILE *f_ = fopen(file, "r"); if (!f_) break; byte *buf = new byte[128]; fread(buf, 128, 1, f_); msg.setPatameter(FILE_TEXT, 128, buf); } } delete p_pata; msg.toString(); s.send(new_fd, msg.getData(), msg.Length()); } s.close(new_fd); } s.close();
return 0;}
|
阅读全文(2302) | 回复(0) | 编辑 | 精华 |
|