封装naive socket
周五去一个公司打了个酱油,面试官问我:你封装过socket没?
言下之意是问我实际写过底层代码没,我悻悻地说写过点。
PS:说实话木有封装过,今天无聊就来封装下。
话说写了这么久C++,底层用c来写还是灰常爽的,C++把它包起来很好看而且好用。
嗯嗯,言归正传,创建了MyTCPSocket:
问题记录1:一旦来了新的链接,就创建一个work线程来处理,但是遇到了小问题:
#pragma once
#include <winsock.h>
#include <stdio.h> #pragma comment(lib, "ws2_32.lib") static DWORD WINAPI WorkerFun(LPVOID aData); class MyTCPSocket
{
public:
MyTCPSocket(void);
~MyTCPSocket(void);
bool Init();
bool UnInit();
bool CreateSocket();
bool Bind(unsigned aPost,const char* aAdress);
bool Listen(int aBacklog=);
bool Connect(unsigned aPost,const char* aAdress);
bool Send(const char* aBuf);
bool Recv();
void Accept(); private:
SOCKET m_Socket;
SOCKET m_ClientSocket;
sockaddr_in m_SockClientaddrIn ;
};
#include "MyTCPSocket.h" MyTCPSocket::MyTCPSocket(void)
:m_Socket(INVALID_SOCKET)
{
} MyTCPSocket::~MyTCPSocket(void)
{
} bool MyTCPSocket::Init()
{
int iResult;
WORD wVersionRequested;
WSADATA wsaData; wVersionRequested = MAKEWORD(, );
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != )
{
printf("WSAStartup failed with error: %d\n", iResult);
return false;
}
else
{
printf("WSAStartup succeeded!\n");
return true;
}
} bool MyTCPSocket::CreateSocket()
{
m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_Socket)
{
printf("INVALID_SOCKET\n");
return false;
}
printf("Create Socket(%d) successully.\n",m_Socket);
BOOL reuseaddr=TRUE;
setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(const char*)&reuseaddr,sizeof(reuseaddr));
return true;
} bool MyTCPSocket::Bind(unsigned aPost,const char* aAdress)
{
struct sockaddr_in server_addr; // server address information
server_addr.sin_family = AF_INET; // host byte order
server_addr.sin_port = htons(aPost); // short, network byte order
server_addr.sin_addr.s_addr = inet_addr(aAdress); // automatically fill with my IP
memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));
if (- == bind(m_Socket,(struct sockaddr *)&server_addr,sizeof(server_addr)))
{
printf("Bind Error.\n");
return false;
} int nRecvBuf = * ; //设置为32K
if (setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)) == -) {
perror("setsockopt");
exit();
}
return true;
} bool MyTCPSocket::Connect( unsigned aPost,const char* aAdress )
{
sockaddr_in lsockaddr_in;
lsockaddr_in.sin_family = AF_INET;
lsockaddr_in.sin_port = htons(aPost);
lsockaddr_in.sin_addr.s_addr = inet_addr(aAdress); if (- == connect(m_Socket,(struct sockaddr *)&lsockaddr_in,sizeof(lsockaddr_in)))
{
printf("Conenct Error.\n");
return false;
}
return true;
} bool MyTCPSocket::Listen( int aBacklog/*=5*/ )
{
if (- == listen(m_Socket,aBacklog))
{
printf("Listen Error.\n");
return false;
}
return true;
} bool MyTCPSocket::Send( const char* aBuf)
{
if (- == send(m_Socket,aBuf,strlen(aBuf)+,))
{
printf("Send Error.\n");
return false;
}
return true;
} bool MyTCPSocket::Recv()
{
char lBuf[];
int lLength = ;
lLength = recv(m_ClientSocket,lBuf,sizeof(lBuf),);
if (SOCKET_ERROR == lLength || == lLength)
{
closesocket(m_ClientSocket);
return false;
}
int lBegin = ;
int lEnd = ;
for (;lEnd < lLength;++lEnd)
{
if ('\0' == lBuf[lEnd])
{
char lData[];
int lLen = lEnd-lBegin;
memcpy(lData,lBuf+lBegin,lLen+);
printf("We successfully received %d byte: %s.\n", lLen, lData);
lBegin = lEnd+;
}
}
if (lEnd < lLength)
{
char lData[];
memcpy(lData,lBuf+lBegin,lEnd-lBegin);
lData[lEnd] = '\0';
printf("We successfully received %d byte: %s.\n", lData);
}
return true;
} bool MyTCPSocket::UnInit()
{
if (- == closesocket(m_Socket))
{
printf("Close Socket Error.\n");
return false;
}
printf("Close Socket(%d).\n",m_Socket);
return true;
} void MyTCPSocket::Accept()
{
int lAddrLen = sizeof(m_SockClientaddrIn);
m_ClientSocket = accept(m_Socket, (sockaddr*)&m_SockClientaddrIn,&lAddrLen); printf("We successfully got a connection from %s:%d.\n",
inet_ntoa(m_SockClientaddrIn.sin_addr), ntohs(m_SockClientaddrIn.sin_port)); HANDLE handle = ::CreateThread(NULL, , WorkerFun,NULL, , NULL);
} DWORD WINAPI WorkerFun( LPVOID aData )
{
printf("Create Worker Thread.\n"); SOCKET lSocket = (SOCKET)(aData); char lBuf[];
int lLength = ;
lLength = recv(lSocket,lBuf,sizeof(lBuf),);
if (SOCKET_ERROR == lLength || == lLength)
{
closesocket(lSocket);
return false;
}
int lBegin = ;
int lEnd = ;
for (;lEnd < lLength;++lEnd)
{
if ('\0' == lBuf[lEnd])
{
char lData[];
int lLen = lEnd-lBegin;
memcpy(lData,lBuf+lBegin,lLen+);
printf("We successfully received %d byte: %s.\n", lLen, lData);
lBegin = lEnd+;
}
}
if (lEnd < lLength)
{
char lData[];
memcpy(lData,lBuf+lBegin,lEnd-lBegin);
lData[lEnd] = '\0';
printf("We successfully received %d byte: %s.\n", lData);
}
return ;
}
测试代码:
#include <stdio.h> #include "MyTCPSocket.h" void ServerStart()
{
MyTCPSocket lServer;
lServer.Init();
lServer.CreateSocket();
lServer.Bind(,"192.168.28.1");
lServer.Listen();
lServer.Accept(); while()
{
if (!lServer.Recv())
{
break;
}
}
lServer.UnInit();
} void ClientStart()
{
MyTCPSocket lServer;
lServer.Init();
lServer.CreateSocket();
if (!lServer.Connect(,"192.168.28.1"))
{
lServer.UnInit();
return;
}
for (int i =; i <;++i)
{
lServer.Send("hell0");
}
lServer.UnInit();
}
int main()
{
ServerStart();
}
表示只是刚开始瞎写,很丑 有木有,赶快改进 有木有!
不过经测试,还是不错滴,博客园有大侠封装的更好的木有,写代码不想注释啊,介个可不可以上首页,大侠猛戳呀,哈哈!
封装naive socket的更多相关文章
- 自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求
DotNet.Net.MySocket是SLB.NET(Server Load Balance服务器负载均衡)项目中的核心组件. 在实际的项目中发现,单进程的服务端处理高并发的客户请求能力有限. 所以 ...
- libevent将信号封装为socket通知的核心代码
#include"stdafx.h" #include"iostream" #include "algorithm" #include&qu ...
- 嵌入式开发之qt socket--- qt 封装的socket demo
http://wuyuans.com/2013/03/qt-socket/ http://blog.chinaunix.net/uid-22480862-id-388253.html
- 封装好的socket,拿去用
年终有空咯,分享一下自己封装的socket类库. 由于公司写的socket代码非常醉人,我不能忍,所以自己封装了一下方便大家使用,现在有空也分享给园友用用看,现在还存在一定的问题,等下我列出来,希望大 ...
- 门面模式的典型应用 Socket 和 Http(post,get)、TCP/IP 协议的关系总结
门面模式的一个典型应用:Socket 套接字(Socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息: 连接使用的 ...
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...
- Socket初识
基础概念 Socket,套接字,本质是网络编程接口.提供网络通信的能力,实现不同虚拟机或不同计算机之间的通信.面向客户/服务(C/S)模型,socket是应用层和传输层之间的中间软件抽象层: 顶上三层 ...
- TCPIP、Http、Socket的协议~ 写得挺形象,赞
这篇文章写得挺形象,对TCPIP.HTTP.Socket的作用有一个整体层次的理解. 转载文章内容如下: 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 通过初步的了 ...
- socket.io简单入门(一.实现简单的图表推送)
引子:随着nodejs蓬勃发展,虽然主要业务系统因为架构健壮性不会选择nodejs座位应用服务器.但是大量的内部系统却可以使用nodejs试水,大量的前端开发人员转入全堆开发也是一个因素. 研究本例主 ...
随机推荐
- 【Spark】开发Spark选择Java还是Scala?
Spark-Java-Scala-哪种语言 spark java 支持_百度搜索 (1 封私信)Spark 中用 Scala 和 java 开发有什么区别? - 知乎 (1 封私信)Spark平台下, ...
- Linq-排序Order By
适用场景:对查询出的语句进行排序,比如按时间排序等等. 说明:按指定表达式对集合排序:延迟,:按指定表达式对集合排序:延迟,默认是升序,加上descending表示降序,对应的扩展方法是OrderBy ...
- Eclipse Maven项目报错3之找不到配置文件spring-servlet-context.xml
一.具体错误如下图所示 根据文字提示可以看出是这个文件找不到,但是我去项目的这个目录找了,这个文件确实存在,那么是什么问题呢 二.解决问题 原因分析(来自网上) 代码编译的过程,是一个自动生成相应编译 ...
- 内建DNS服务器--BIND
参考 BIND 官网:http://www.isc.org/downloads/bind/ 1.系统环境说明 [root@clsn6 ~]# cat /etc/redhat-release CentO ...
- 轻量级分布式文件系统FastDFS使用安装说明手册(新手入门级)
轻量级分布式文件系统FastDFS使用安装说明手册(新手入门级) 实验室所在的课题组以研究云计算为主,但所有的研究都是在基于理论的凭空想像,缺少分布式环境的平台的实践,云计算神马的都是浮云了.因此,我 ...
- Bridging and Bonding with CentOS 6.5
eth0和eth1要做bond,然后kvm虚拟机通过bridge与外界通信. 那么就要在bond上做bridge.配置文件例如以下,实測这样配置,能够从kvm虚拟机ping通外界拓扑. ifcfg-e ...
- SWIFT学习笔记05
1.Swift 无需写break,所以不会发生这样的贯穿(fallthrough)的情况.2.//用不到变量名,可用"_"替换 for _ in 1...power { answe ...
- 【树莓派】树莓派与XBMC及Kodi、LibreELEC插件(一)
网上高人多. 高手在民间,饭桶在机关. 越用树莓派,越发现这玩意儿的潜力,我想,未来我们用它,可以做很多事情. 最近在看树莓派的应用场景,看到网上有人用它做电视盒子. 参考相关文章,简单实践了一下,整 ...
- 微信小程序 - async/await
下面只是做一些介绍以及使用的原因,详情介绍还请移步博主:https://www.cnblogs.com/SamWeb/p/8417940.html regenerator-runtime下载:http ...
- Sqoop拒绝连接错误
使用Sqoop远程连接MySQL导入数据到HBase数据库: sqoop import --driver com.mysql.jdbc.Driver --connect "jdbc:mysq ...