#ifndef NETSOCKET_H
#define NETSOCKET_H
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include<sys/un.h>
#include <unistd.h>
#include <stdio.h>
#include<arpa/inet.h>
#include <fcntl.h>
class NetSocket
{
private:
/* data */
public:
NetSocket(/* args */);
~NetSocket();
/***********目前tcp 只能1对1****************/
int tcpSvrInit(int port);
int tcpSvrDeInit();
int tcpCliInit(char *IP,int port);
int tcpCliDeInit();
int tcpRcv(char *pBuff,int pLen);
int tcpSnd(char *pBuff,int pLen);
/***********udp服务端客户端一样****************/
//局部链接多播地址范围在 224.0.0.0~224.0.0.255,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包;
//预留多播地址为 224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议;
//管理权限多播地址为 239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有 IP 地址,不能用于 Internet,可限制多播范围。
//udpMode 0普通 1组播 2广播
int udpSvrCliInit(char *IP,int port,char udpMode,char isBlock);
int udpSvrCliDeInit();
int udpRcv(char *pBuff,int pLen);
int udpSnd(char *pBuff,int pLen);
int udpLocalInit(char *selfFilePath,char *remoteFilePath);
int udpLocalDeInit();
int udpLocalRcv(char *pBuff,int pLen);
int udpLocalSnd(char *pBuff,int pLen);
int socketFd;//cosket fd
int connSocketFd;//
struct sockaddr_in selfAddr;//自己地址信息 不同主机用sockaddr_in
struct sockaddr_in remoteAddr;//远程地址信息
struct sockaddr_un selfAddrLocal;//自己地址信息 同主机用sockaddr_un
struct sockaddr_un remoteAddrLocal;//远程地址信息
};
#endif
#include "netSocket.h"
NetSocket::NetSocket(/* args */)
{
socketFd=0;
connSocketFd=0;
}
NetSocket::~NetSocket()
{
}
int NetSocket::tcpSvrInit(int port)
{
//创建一个TCP的socket
if( (socketFd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf(" create socket error: %s (errno :%d)\n",strerror(errno),errno);
return -1;
}
//先把地址清空,检测任意IP
memset(&selfAddr,0,sizeof(selfAddr));
selfAddr.sin_family = AF_INET;
selfAddr.sin_addr.s_addr = htonl(INADDR_ANY);
selfAddr.sin_port = htons(port);
//地址绑定到listenfd
if ( bind(socketFd, (struct sockaddr*)&selfAddr, sizeof(selfAddr)) == -1)
{
printf(" bind socket error: %s (errno :%d)\n",strerror(errno),errno);
tcpSvrDeInit();
return -1;
}
//监听listenfd
if( listen(socketFd,10) == -1)
{
printf(" listen socket error: %s (errno :%d)\n",strerror(errno),errno);
tcpSvrDeInit();
return -1;
}
socklen_t addrlen = sizeof(remoteAddr);
if((connSocketFd = accept(socketFd,(struct sockaddr *)&remoteAddr,&addrlen)) < 0)
{
printf(" accept socket error: %s (errno :%d)\n",strerror(errno),errno);
tcpSvrDeInit();
return -1;
}
char ipv4_addr[16];
if(!inet_ntop(AF_INET,(void *)&remoteAddr.sin_addr,ipv4_addr,sizeof(remoteAddr)))
{
printf(" inet_ntop socket error: %s (errno :%d)\n",strerror(errno),errno);
tcpSvrDeInit();
return -1;
}
printf("Client(%s:%d) is connected!\n",ipv4_addr,htons(remoteAddr.sin_port));
}
int NetSocket::tcpSvrDeInit()
{
if(connSocketFd!=NULL)
close(connSocketFd);
connSocketFd=0;
if(socketFd!=NULL)
close(socketFd);
socketFd=0;
}
int NetSocket::tcpCliInit(char *IP,int port)
{
//创建socket
if( (socketFd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf(" create socket error: %s (errno :%d)\n",strerror(errno),errno);
tcpCliDeInit();
return -1;
}
memset(&selfAddr,0,sizeof(selfAddr));
selfAddr.sin_family = AF_INET;
selfAddr.sin_port = htons(port);
//IP地址从“点分十进制”转换到“二进制整肃”
if( inet_pton(AF_INET,IP, &selfAddr.sin_addr) <=0 )
{
printf("inet_pton error for %s\n",IP);
tcpCliDeInit();
return -1;
}
//连接
if( connect(socketFd,(struct sockaddr*)&selfAddr,sizeof(selfAddr)) <0)
{
printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
tcpCliDeInit();
return -1;
}
connSocketFd=socketFd;//注意,是为了保持发送接收和服务端一致特殊修改的
}
int NetSocket::tcpCliDeInit()
{
if(socketFd!=NULL)
close(socketFd);
socketFd=0;
connSocketFd=0;
}
int NetSocket::tcpRcv(char *pBuff,int pLen)
{
memset(pBuff, 0, sizeof(pBuff));
int tempLen = recv(connSocketFd, pBuff, pLen, 0);
return tempLen;
}
int NetSocket::tcpSnd(char *pBuff,int pLen)
{
return send(connSocketFd, pBuff, pLen,MSG_NOSIGNAL);
}
int NetSocket::udpSvrCliInit(char *IP,int port,char udpMode,char isBlock)
{
//1 创建udp通信socket
socketFd = socket(AF_INET, SOCK_DGRAM, 0);
if(socketFd == -1)
{
perror("socket failed!\n");
return -1;
}
//设置目的IP地址
memset(&remoteAddr,0x00,sizeof(remoteAddr));
remoteAddr.sin_family = AF_INET;//使用IPv4协议
remoteAddr.sin_port = htons(port);//设置接收方端口号
remoteAddr.sin_addr.s_addr = inet_addr(IP); //设置接收方IP
memset(&selfAddr,0x00,sizeof(selfAddr));
selfAddr.sin_family = AF_INET; //使用IPv4协议
selfAddr.sin_port = htons(port); //网络通信都使用大端格式
selfAddr.sin_addr.s_addr = INADDR_ANY;//让系统检测本地网卡,自动绑定本地IP
if(isBlock!=0x00)
{
int flag = fcntl(socketFd, F_GETFL, 0);
if (flag < 0)
{
printf(" fcntl1 socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}
flag |= O_NONBLOCK;
if (fcntl(socketFd, F_SETFL, flag) < 0)
{
printf(" fcntl2 socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}
}
int ret = bind(socketFd,(struct sockaddr*)&selfAddr,sizeof(selfAddr));
if(ret < 0)
{
printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}
else
{
printf("recv ready--%d\n",socketFd);
}
if(udpMode==1)
{
unsigned char loop=0;//禁止回环
setsockopt(socketFd,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop));
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(IP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
ret=setsockopt(socketFd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
if(ret<0){
printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}else
{
printf("add to group success\n");
}
}
else if(udpMode==2)
{
unsigned char loop=0;//禁止回环
setsockopt(socketFd,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop));
unsigned char so_boradcast=1;
ret=setsockopt(socketFd,SOL_SOCKET,SO_BROADCAST,&so_boradcast,sizeof(so_boradcast));
if(ret<0){
printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}else
{
printf("add to brocast success\n");
}
}
}
int NetSocket::udpSvrCliDeInit()
{
if(socketFd!=NULL)
close(socketFd);
socketFd=0;
connSocketFd=0;
}
int NetSocket::udpRcv(char *pBuff,int pLen)
{
int len = sizeof(selfAddr);
return recvfrom(socketFd, pBuff, pLen, 0, (struct sockaddr *)&selfAddr, (socklen_t *)&len);
}
int NetSocket::udpSnd(char *pBuff,int pLen)
{
return sendto(socketFd, pBuff, pLen, 0, (struct sockaddr *)&remoteAddr,sizeof(remoteAddr));
}
int NetSocket::udpLocalInit(char *selfFilePath,char *remoteFilePath)
{
socketFd = socket(AF_LOCAL, SOCK_DGRAM, 0);
if(socketFd < 0)
{
printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
return -1;
}
remoteAddrLocal.sun_family = AF_LOCAL;
strcpy(remoteAddrLocal.sun_path, remoteFilePath);
selfAddrLocal.sun_family = AF_LOCAL;
strcpy(selfAddrLocal.sun_path, selfFilePath);
unlink(selfAddrLocal.sun_path);
if(1)
{
int flag = fcntl(socketFd, F_GETFL, 0);
if (flag < 0)
{
printf(" fcntl1 socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}
flag |= O_NONBLOCK;
if (fcntl(socketFd, F_SETFL, flag) < 0)
{
printf(" fcntl2 socket error: %s(errno :%d)\n",strerror(errno),errno);
udpSvrCliDeInit();
return -1;
}
}
if(bind(socketFd, (struct sockaddr*)&selfAddrLocal, sizeof(selfAddrLocal)) < 0)
{
printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
udpLocalDeInit();
return -1;
}
}
int NetSocket::udpLocalDeInit()
{
if(socketFd!=NULL)
close(socketFd);
socketFd=0;
connSocketFd=0;
}
int NetSocket::udpLocalRcv(char *pBuff,int pLen)
{
int len = sizeof(selfAddrLocal);
return recvfrom(socketFd, pBuff, pLen, 0, (struct sockaddr *)&selfAddrLocal, (socklen_t *)&len);
}
int NetSocket::udpLocalSnd(char *pBuff,int pLen)
{
return sendto(socketFd, pBuff, pLen, 0, (struct sockaddr *)&remoteAddrLocal,sizeof(remoteAddrLocal));
}
int main(int argc, char *argv[])
{
// 打印每个命令行参数的值
for (int i = 0; i < argc; i++)
{
printf("Argument %d: %s\n", i, argv[i]);
}
NetSocket mNetSocket;
mNetSocket.udpLocalInit(argv[1],argv[2]);
while(1)
{
char temp[1024]={0x00};
int len=mNetSocket.udpLocalRcv(temp,1024);
if(len>0)
{
printf("rcv:%s\n",temp);
}
usleep(1000000);
printf("snd:1234567890\n");
mNetSocket.udpLocalSnd("1234567890",10);
}
}