前排叠个甲:为什么现在才学习到Linux套接字???我的回答是:大一玩了一年,大二开始接触C++,其中呢,大二上学习完了Qt,大二下才开始接触Linux,而在这期间,反复阅读了C++的特性源码....所以。
回归正题:直接放代码,没什么好说的,就那一套流程:
服务器端的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
typedef struct socketAndfd{
struct sockaddr_in ip_port;
int _fd;
}client_info;
void do_thing(std::list<client_info>& list,const client_info info,int flag){
//5.连接建立成功,打印客户端的IP和端口信息
char ip_client[32];
printf("客户端的IP:%s,端口:%d\n",inet_ntop(AF_INET,&info.ip_port.sin_addr.s_addr,ip_client,sizeof(ip_client)),ntohs(info.ip_port.sin_port));
//6.通知
while(1){
//接受数据
char buff[1024];
memset(buff,0,sizeof(buff));
int len=recv(info._fd,buff,sizeof(buff),0);
if(len>0){
printf("client say:%s\n",buff);
send(info._fd,buff,len,0); //重新发送回去
}
else if(0==len){
printf("客户端已经断开了连接...\n");
break;
}
else{
printf("revc");
break;
}
}
//关闭文件描述符
close(info._fd);
auto it=list.begin();
std::advance(it,flag);
list.erase(it);
}
int main()
{
//1.创建监听用到的套接字
int fd=socket(AF_INET,SOCK_STREAM,0);
if(fd==-1){
perror("socket");
return -1;
}
//2.绑定本地的IP port
struct sockaddr_in saddr;
saddr.sin_family=AF_INET;
saddr.sin_port=htons(9999);
saddr.sin_addr.s_addr=INADDR_ANY;
int ret=bind(fd,(struct sockaddr*)&saddr,sizeof(saddr));
if(-1==ret){
perror("bind");
return -1;
}
//3.设置监听
ret=listen(fd,128);
if(-1==ret){
perror("listen");
return -1;
}
//链表维护多个客户端的信息
std::list<client_info> list;
//数组维护多个线程信息
std::vector<std::thread> _thread;
//指示器用以当一个线程结束时销毁链表资源
int sizeof_list=0;
//临时变量
client_info temp;
socklen_t ofsockaddr_in=sizeof(temp.ip_port);
//4.阻塞并等待客户端的连接
while(1){
{
int cfd=accept(fd,(struct sockaddr*)&(temp.ip_port),&ofsockaddr_in);
temp._fd=cfd;
list.push_back(temp);
}
if(-1==temp._fd){
perror("accept");
//销毁错误资源
auto temp_it=list.begin();
std::advance(temp_it,sizeof_list);
list.erase(temp_it);
continue;
}
//如果有新的连接,开启一个新的线程
else{
auto temp_it=list.begin();
std::advance(temp_it,sizeof_list);
_thread.emplace_back(do_thing,std::ref(list),*(temp_it),sizeof_list);
sizeof_list++;
}
}
for(auto &it:_thread){
it.join();
}
close(fd);
return 0;
}
接下来是客户端的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
int main()
{
//1.创建通信用到的套接字
int fd=socket(AF_INET,SOCK_STREAM,0);
if(fd==-1){
perror("socket");
return -1;
}
//2.连接服务器IP port
struct sockaddr_in saddr;
saddr.sin_family=AF_INET;
saddr.sin_port=htons(9999);
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr.s_addr);
//3.连接服务器
int ret=connect(fd,(struct sockaddr*)&saddr,sizeof(saddr));
if(-1==ret){
perror("connect");
return -1;
}
//3.通知
int number=0;
while(1){
//发送数据
char buff[1024];
sprintf(buff,"你好,服务器...%d\n",number++);
send(fd,buff,strlen(buff)+1,0);
//接受数据
memset(buff,0,sizeof(buff));
int len=recv(fd,buff,sizeof(buff),0);
if(len>0){
printf("server says:%s\n",buff);
}
else if(0==len){
printf("Server端已经断开了连接...\n");
break;
}
else{
printf("revc");
break;
}
sleep(1);
}
//关闭文件描述符
close(fd);
return 0;
}