这是我第一次尝试性的发篇博客,记述我用C/C++ 在Linux环境下socket网络通信,客户端和服务端通信使用包头,包体来解决粘包。以下是我的一些见解,和客户端和服务端的代码。希望可以帮助到同在学习的大家。
首先C/C++ 不是跨平台的,因此在window环境和Linux环境使用的函数是不一样的,我使用的是Linux平台的。
虽然用的是Linux环境,但我们不用专门下个虚拟机装Linux,win10 可以开启Linux子系统
大家手动换台 : https://jingyan.baidu.com/article/624e74596633a034e8ba5a2b.html
现在展示下程序的效果
除此之外我还加了管理员,不过功能还只能看 消息记录
服务端的代码如下:
#include
#include
using namespace std;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFMAX 1024
#define FILENAME "share.txt"
struct packet
{
int len;
char name[16]; //4+16->20
char buf[BUFMAX];
};
void func(int flag)
{
cout<<"write进程退出"<0)
{
if( (nread=read(fd,bufp,nleft))<=0 )
{
cout<<"连接中断"<0)
{
nwrite=write(fd,bufp,nleft);
nleft-=nwrite;
bufp+=nwrite;
}
return count;
}
void root_usr(int connectfd) // root 用户
{
int ret,len;
packet pack;
memset(pack.name,0,16);
while(1)
{
strcpy(pack.buf,
"**********欢迎 Root 管理员**********\n\n1 . 查看聊天记录\n 2 . 删除聊天记录\n 乱按 -》 退出 \n");
len=strlen(pack.buf)+1;
pack.len=htonl(len);
writen(connectfd,&pack,len+20);
ret=read(connectfd,&pack,4);
if(ret<=0)
return;
len=ntohl(pack.len);
ret=read(connectfd,&pack.name,len+16);
if(ret<=0)
return;
if( strlen(pack.buf)!=1 )
{cout<0) //父进程 接受数据
{
pack=(struct packet *)shmat(shmid, (void*)0, 0);
if(pack==(void *)-1)
cout<<"shmat失败"<len);
num=readn(connectfd,pack->name,nlen+16);
test(pid,num);
cout<name<<" : "<buf<name)!=0 )
{
if( strcmp(name_tmp,pack->name)||strcmp(buf_tmp,pack->buf) )
{
break;
}
}
}
strcpy(name_tmp,pack->name);
strcpy(buf_tmp,pack->buf) ;
nlen=strlen(pack->buf)+1; // 有'\0'
int zz=write(connectfd,pack,nlen+20);
if(zz<=0)
cout<<"************write 失败 ***"<1) //父进程 继续监听
close(connectfd);
else
{
cout<<"1pid错误"<
服务端代码如下:
#include
using namespace std;
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFMAX 1024
struct packet
{
int len;
char name[16];
char buf[BUFMAX];
};
void test(pid_t pid,int num)
{
if(num<=0)
{
if(num==0)
{
cout<<"连接中断 read进程关闭"<0)
{
if( (nread=read(fd,bufp,nleft))<=0 )
{
cout<<"*****nead"<0)
{
if( (nwrite=write(fd,bufp,nleft))<=0 )
{
cout<<"连接中断"<>pack.name;
pid=fork();
if(pid>0)
{
while(1)
{
num=readn(connectfd,&pack,4);
test(pid,num);
nlen=ntohl(pack.len);
num=readn(connectfd,pack.name,nlen+16);
test(pid,num);
cout<>pack.buf;
nlen=strlen(pack.buf)+1; // '\0'
pack.len=htonl(nlen);
write(connectfd,&pack,nlen+20);
//memset(pack.buf,0,nlen);
}
}
else
cout<<"pid错误"<
如果大家觉得在本机上面测试无聊的话,可以在阿里云买一个Linux服务器,有学生证的话很便宜,把服务端程序放
上去,客户端代码的IP地址改成阿里云分配的公网IP,还有服务端和客户端的端口号改成阿里云允许的端口。这样你电脑
的客户端程序就可以跟别人的电脑的客户端通信了,就跟微信群聊 “差不多” 了。 如果觉得客户端太丑了,可以用其他
语言写一个界面,现在我就是和同学一起弄了,我专门服务端 ,同学则用C#重新写一份带图像界面的客户端