您的位置:首页 > 编程语言 > C语言/C++

Dev-cpp下的一个socket的例子

2008-03-15 20:59 281 查看
这两天自己准备做一个小型C/S结构的演示工具,需要用到socket的编程。在网上看了很多帖子,发现许多人都在找“一个简单的socket”例子。而网上大多是对socket编程进行说明。最后看来看去,可能有些人还是摸不到门。我自己也走了几步弯路,才搭起一个C/S结构的小例子。下面,我把这个简单的例子放到自己的日志中,希望能对看到它的人,当然也包括我自己有一个初窥socket编程的概念。

这个例子很简单,服务端是单线程的,一般来说实际应用中多采用多线程方式监听客户请求的。我会再找时间将写一个这个例子的升级版本(多线程)。

先列客户端的代码:Client.h


#ifndef _SERVERSOCKET_H


#define _SERVERSOCKET_H


#include <sys/types.h>


//! 下面是根据操作系统自动加载所需的库和头文件


#ifdef WIN32


#include <winsock2.h>


#pragma comment(lib,"ws2_32.lib")


#else


#include <sys/socket.h>


#endif


#include <string>


#include <iostream>


int WSAStartup


(


WORD wVersionRequested,


LPWSADATA lpWSAData


);




using namespace std;


class CClient




...{


int m_sockfd;


struct sockaddr_in m_addr;


public:


CClient(const string& strAddr, int iPort);


~CClient();


BOOL Connect();


};


#endif

定义文件Client.cpp


#include "Client.h"


CClient::CClient(const string& strAddr, int iPort)




...{


WSADATA wsaData;


int err = WSAStartup( MAKEWORD(2, 2), &wsaData );


if (err == SOCKET_ERROR)


cout << "WSAStartup error" << endl;


m_sockfd = socket(AF_INET, SOCK_STREAM, 0); /*需要错误检查 */


if (m_sockfd == -1)




...{


cout << "socket fail!" << endl;


return;


}


cout << "socket success!socket:" << m_sockfd << endl;


memset(&m_addr, 0x00, sizeof(m_addr));




m_addr.sin_family = AF_INET; /**//* host byte order */




m_addr.sin_port = htons(iPort); /**//* short, network byte order */


m_addr.sin_addr.s_addr = inet_addr(strAddr.c_str());


}




CClient::~CClient()




...{


WSACleanup();


}




BOOL CClient::Connect()




...{


int iRet = connect(m_sockfd, (struct sockaddr *)&m_addr, sizeof(m_addr));


if (iRet == -1)




...{


cout << "connect fail!" << endl;


return FALSE;


}


return TRUE;


}




BOOL CClient::Send(const string& strSend)




...{


int iRet = send(m_sockfd, strSend.c_str(), strSend.length(), 0);


if (iRet == -1)




...{


cout << "connect fail!" << endl;


return FALSE;


}


cout << "Send is OK!";


return TRUE;


}

上面的例子中我把较多的初始化处理直接放在了构造函数中,这个习惯不是很好。不过只是一个简单举例,所以我就不修改它了。客户端的主文件如下:


#include <stdlib.h>


#include "Client.h"




int main(int argc, char *argv[])




...{


CClient cc("127.0.0.1", 8001); //! 第一个参数是本机IP地址,第二参数是自选的端口号


cc.Connect();


cc.Send("Send Message!");


system("PAUSE");


return 0;


}

下面是服务端的头文件:Server.h


#ifndef _SERVERSOCKET_H


#define _SERVERSOCKET_H


#include <sys/types.h>


#ifdef WIN32


#include <winsock2.h>


#pragma comment(lib,"ws2_32.lib")


#else


#include <sys/socket.h>


#endif


#include <string>


#include <iostream>


#define SERVER_PORT 8001


#define MAX_BUFFER_LENGTH 2048




using namespace std;


class CServer




...{


int m_sockfd;


struct sockaddr_in m_addr;public:


CServer(const string& strAddr);


~CServer();


BOOL Start();


BOOL Stop();


};


#endif

对应的定义文件:


#include "Server.h"




CServer::CServer(const string& strAddr)




...{


WSADATA wsaData;


int err = WSAStartup( MAKEWORD(2, 2), &wsaData );


if (err == SOCKET_ERROR)




...{


cout << "WSAStartup error" << endl;


return;


}




m_sockfd = socket(AF_INET, SOCK_STREAM, 0); /**//*需要错误检查 */




m_addr.sin_family = AF_INET; /**//* host byte order */




m_addr.sin_port = htons(SERVER_PORT); /**//* short, network byte order */


m_addr.sin_addr.s_addr = inet_addr(strAddr.c_str());


}




CServer::~CServer()




...{


WSACleanup();


}




BOOL CServer::Start()




...{


int iret = bind(m_sockfd, (struct sockaddr *)&m_addr, sizeof(struct sockaddr));


if (iret == -1)




...{


cout << "bind fail" << endl;


return FALSE;


}


cout << "bind OK" << endl;


listen(m_sockfd, 3);


cout << "listening..." << endl;


struct sockaddr_in their_addr;


int sin_size = sizeof(struct sockaddr_in);


int getsockfd = accept(m_sockfd,(struct sockaddr *)&their_addr,&sin_size);


cout << "accepted" << endl;




char buf[MAX_BUFFER_LENGTH] = ...{0};


if (!getsockfd)




...{


return FALSE;


}


cout << "Starting Server...!" << endl;


int recvLen = 0;


do




...{


recvLen = recv(getsockfd, buf, sizeof(buf)/sizeof(buf[0]), 0);


}while(recvLen == -1);


cout << buf << endl;


return TRUE;


}




BOOL CServer::Stop()




...{


//close(m_sockfd); //! 这个地方如果去掉前面的注释符,编译会报错。


//! 我暂时还没有去了解原因。按道理应该要关闭的。


return TRUE;


}

服务端主文件内容如下:


#include <iostream>


#include <stdlib.h>


#include "Server.h"


using namespace std;




int main(int argc, char *argv[])




...{


CServer cs("127.0.0.1"); //! 和客户端不同,我在代码中定义了端口号,你也可以在外边定义,增加灵活性


cs.Start();


system("PAUSE");


return 0;


}

以上代码我在Dev-C++ 4.9.7.0下编译运行通过。希望对大家有点入门的参考作用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: