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下编译运行通过。希望对大家有点入门的参考作用。
这个例子很简单,服务端是单线程的,一般来说实际应用中多采用多线程方式监听客户请求的。我会再找时间将写一个这个例子的升级版本(多线程)。
先列客户端的代码: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下编译运行通过。希望对大家有点入门的参考作用。
相关文章推荐
- 一个不错的多线程Socket服务器简单例子
- 一个Android Socket的例子
- 通过一个Socket例子理解Http协议(实战Java Web服务器--使用HTTP协议和JAVA类实现)
- 一个最简单的Socket通信例子
- 一个 Java 的 Socket 服务器和客户端通信的例子
- 非阻塞方式下Socket读取数据的一个例子
- 一个 Java 的 Socket 服务器和客户端通信的例子
- 一个Socket编程的例子
- Java 的 Socket 服务器和客户端通信的例子 存在一个小问题
- libmysqlcppconn-dev : 依赖: libboost-dev 但是它将不会被安装 一个解决办法
- 非阻塞方式下Socket读取数据的一个例子
- 一个select接收socket数据的例子
- 一个Socket应用的例子,分享给大家
- socket编程——一个简单的例子
- Qt的Socket数据通讯的一个例子。
- 一个关于linux socket的简单例子
- socket编程——一个简单的例子
- win32 socket的一个简单的例子 控制台
- 一个 Java 的 Socket 服务器和客户端通信的例子
- 如何在DEV-CPP中使用winsocket API