通信类
tcpSocket.h
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
class TCPSocket
{
private:
int m_fd;
int readn(char *buf,int size);
int writen(const char *msg,int size);
public:
TCPSocket();
TCPSocket(int sock);
~TCPSocket();
int connectToHost(string ip,unsigned short port);
int sendMsg(string msg);
string recvMsg();
};
#endif
tcpSocket.cpp
#include "tcpSocket.h"
TCPSocket::TCPSocket()
{
m_fd=socket(AF_INET,SOCK_STREAM,0);
}
TCPSocket::TCPSocket(int sock)
{
m_fd=sock;
}
TCPSocket::~TCPSocket()
{
if (m_fd>0)
{
close(m_fd);
}
}
int TCPSocket::connectToHost(string ip,unsigned short port)
{
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(sockaddr_in));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(port);
saddr.sin_addr.s_addr=inet_addr(ip.data());
int ret=connect(m_fd,(struct sockaddr*)&saddr,sizeof(saddr));
if (ret==-1)
{
perror("connect");
return -1;
}
cout<<"conncet server 成功..."<<endl;
return ret;
}
int TCPSocket::sendMsg(string msg)
{
char *data=new char[msg.size()+4];
int bigLen=htonl(msg.size());
memcpy(data,&bigLen,4);
memcpy(data+4,msg.data(),msg.size());
int ret=writen(data,msg.size()+4);
delete[] data;
return ret;
}
string TCPSocket::recvMsg()
{
int len=0;
readn((char*)&len,4);
len=ntohl(len);
char *buf=new char[len+1];
int ret=readn(buf,len);
if (ret!=len)
{
return string();
}
buf[len]='\0';
string retStr(buf);
delete[] buf;
return retStr;
}
int TCPSocket::readn(char *buf,int size)
{
int nread=0;
int left=size;
char *p=buf;
while(left>0)
{
if ((nread=read(m_fd,p,left))>0)
{
p+=nread;
left-=nread;
}
else if(nread==-1)
{
return -1;
}
}
return size;
}
int TCPSocket::writen(const char *msg,int size)
{
int left=size;
int nwrite=0;
const char*p=msg;
while (left>0)
{
if ((nwrite=write(m_fd,msg,left))>0)
{
p+=nwrite;
left-=nwrite;
}
else if (nwrite==-1)
{
return -1;
}
}
return size;
}
服务类
tcpServer.h
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "tcpSocket.h"
class TCPServer
{
private:
int m_fd;
public:
TCPServer();
~TCPServer();
int setListen(string ip,unsigned short port);
TCPSocket * acceptConn(struct sockaddr_in * addr=nullptr);
};
#endif
tcpServer.cpp
#include "tcpServer.h"
TCPServer::TCPServer()
{
m_fd=socket(AF_INET,SOCK_STREAM,0);
}
TCPServer::~TCPServer()
{
close(m_fd);
}
int TCPServer::setListen(string ip,unsigned short port)
{
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(sockaddr_in));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(port);
saddr.sin_addr.s_addr=inet_addr(ip.data());
int ret=bind(m_fd,(struct sockaddr*)&saddr,sizeof(saddr));
if (ret==-1)
{
perror("bind");
return -1;
}
cout<<"bind 成功..."<<endl;
cout<<"ip: "<<inet_ntoa(saddr.sin_addr)<<" port: "<<port<<endl;
ret=listen(m_fd,128);
if (ret==-1)
{
perror("listen");
return -1;
}
cout<<"设置listen 成功..."<<endl;
return ret;
}
TCPSocket * TCPServer::acceptConn(struct sockaddr_in * addr)
{
if (addr==NULL)
{
return nullptr;
}
socklen_t addrlen=sizeof(struct sockaddr_in);
int cfd=accept(m_fd,(struct sockaddr*)addr,&addrlen);
if (cfd==-1)
{
perror("accept");
return nullptr;
}
cout<<"connect 客户端 成功..."<<endl;
return new TCPSocket(cfd);
}
客户端
client.cpp
#include <iostream>
#include <fcntl.h>
#include "tcpSocket.h"
int main()
{
TCPSocket tcp;
int ret=tcp.connectToHost("127.0.0.1",8080);
if (ret==-1)
{
return -1;
}
int fd1=open("test.txt",O_RDONLY);
int length=0;
char tmp[100];
memset(tmp,0,sizeof(tmp));
cout<<"send msg"<<endl;
while((length=read(fd1,tmp,sizeof(tmp)))>0)
{
tcp.sendMsg(string(tmp,length));
cout<<tmp;
memset(tmp,0,sizeof(tmp));
usleep(300);
}
sleep(10);
return 0;
}
服务端
server.cpp
#include <iostream>
#include <fcntl.h>
#include <pthread.h>
#include "tcpSocket.h"
#include "tcpServer.h"
using namespace std;
struct SockInfo
{
TCPServer *s;
TCPSocket *tcp;
struct sockaddr_in addr;
};
void *working(void *arg)
{
struct SockInfo *pinfo=static_cast<struct SockInfo*>(arg);
char ip[32];
cout<<"ip: "<<inet_ntop(AF_INET,&(pinfo->addr.sin_addr.s_addr),ip,sizeof(ip));
cout<<" port: "<<ntohs(pinfo->addr.sin_port);
cout<<"接收数据..."<<endl;
while (1)
{
string msg=pinfo->tcp->recvMsg();
if (!msg.empty())
{
cout<<msg;
}
else
{
break;
}
}
delete pinfo->tcp;
delete pinfo;
return nullptr;
}
int main()
{
TCPServer s;
s.setListen("127.0.0.1",8080);
while (1)
{
SockInfo *info=new SockInfo;
TCPSocket *tcp=s.acceptConn(&info->addr);
if (tcp==nullptr)
{
cout<<"重试..."<<endl;
continue;
}
pthread_t tid;
info->s=&s;
info->tcp=tcp;
pthread_create(&tid,NULL,working,info);
pthread_detach(tid);
}
return 0;
}