好友
阅读权限10
听众
最后登录1970-1-1
|
蟹老板阿
发表于 2020-12-28 22:38
分为C语言版和C++版
C语言版为简单的单向socket通信
C++版本为socket的聊天室通信版本
使用到多线程,编译的时候加上参数 -lpthread
以下是代码
c语言版本
[C] 纯文本查看 复制代码 #include <iostream>
// 文件名:client.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string>
#define MAX 4096
int main()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in ser_addr;
char recvline[100],sendline[100];
if (sockfd == -1)
{
std::cout << "create socket error" << std::endl;
printf("error");
return 0;
}
std::cout << "create successful" << std::endl;
memset(&ser_addr,0,sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(7788);
ser_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//inet_pton(AF_INET,"192.168.0.2",&ser_addr.sin_addr);
std::cout << "create successful" << std::endl;
int temp = connect(sockfd,(const struct sockaddr*)&ser_addr,sizeof(ser_addr));
std::cout << "create successful" << std::endl;
if(temp < 0)
{
std::cout << "connect error" << std::endl;
return 0;
}
std::cout << "Msg you can send:" << std::endl;
//std::cin >> sendline;
while(1)
{
std::cin >> sendline;
if(sendline[0] == 'q' && sendline[1] == '\0')
{
break;
}
if (send(sockfd,(const void*)&sendline,strlen((const char*)&sendline),0) < 0)
{
std::cout << "send message error" << std::endl;
return 0;
}
memset(&sendline,0,sizeof(sendline));
}
// if (send(sockfd,(const void*)&sendline,strlen((const char*)&sendline),0) < 0)
// {
// std::cout << "send message error" << std::endl;
// return 0;
// }
close(sockfd);
return 0;
}
[C] 纯文本查看 复制代码 #include <iostream>
//文件名:service.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string>
#include <thread>
#define MAX 4096
int main()
{
int listenfd,connfd;
struct sockaddr_in ser_addr;
char buff[MAX];
int n;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
{
std::cout << "create socket error" << std::endl;
//printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
std::cout << "create successful" << std::endl;
memset(&ser_addr,0,sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//ser_addr.sin_addr.s_addr = inet_addr("192.168.0.1");
ser_addr.sin_port = htons(7788);
if(bind(listenfd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) == -1)
{
std::cout << "bind socket error" << std::endl;
return 0;
}
if(listen(listenfd,10) == -1)
{
std::cout << "failed to listen the socket" << std::endl;
return 0;
}
std::cout << "listen success" << std::endl;
int socketlen = sizeof(struct sockaddr_in);
struct sockaddr_in client_addr;
if( (connfd = accept(listenfd,(struct sockaddr*)&client_addr,(socklen_t*)&socketlen)) == -1)
{
std::cout << "accept socket error" << std::endl;
}
while(1)
{
// if( (connfd = accept(listenfd,(struct sockaddr*)&client_addr,(socklen_t*)&socketlen)) == -1)
// {
// std::cout << "accept socket error" << std::endl;
// continue;
// }
n = recv(connfd,buff,MAX,0);
if(n > 0)
{
buff[n] = '\0';
std::cout << buff << std::endl;
}
//close(connfd);
memset(&buff,0,sizeof(buff));
}
close(listenfd);
return 0;
}
-----------------------分割线,以下为cpp的聊天室版本------------------------------------
[C++] 纯文本查看 复制代码 #include <iostream>
//文件名:C_client.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string>
#include <thread>
#define MAX 4096
using namespace std;
class Client
{
public:
Client();
~Client();
char* get_sendbuff();
void created_socket();
int connect_socket();
int send_socket(int,char*);
void close_socket();
int get_sockfd();
void recv_socket();
struct msgData
{
int id;
char msg[MAX];
};
private:
int sendfd;
int socketfd;
struct sockaddr_in ser_addr;
char recvbuff[MAX];
char sendbuff[MAX];
int connfd;; //定义connect句柄
int recvnum; //定义recv句柄
};
Client::Client()
{
socketfd = socket(AF_INET, SOCK_STREAM, 0);
memset((void*)&ser_addr,0,sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
ser_addr.sin_port = htons(7788);
memset(sendbuff,0,sizeof(sendbuff));
}
Client::~Client()
{
}
void Client::created_socket()
{
if(socketfd == -1)
{
std::cout << "create socket error! " << std::endl;
}
else
{
std::cout << "create socket success..." << std::endl;
}
}
int Client::connect_socket()
{
connfd = connect(socketfd,(const struct sockaddr*)&ser_addr,sizeof(ser_addr));
if (connfd < 0)
{
std::cout << "connect socket error" << std::endl;
return -1;
}
else
{
std::cout << "connfd is " << connfd << std::endl;
std::cout << "connect socket success " << std::endl;
return 0;
}
}
int Client::send_socket(int sockfd,char* sendline)
{
sendfd = send(sockfd,(const void*)sendline,strlen((const char*)sendline),0);
if (sendfd < 0)
{
std::cout << "send message failed..." << std::endl;
return -1;
}
}
void Client::recv_socket()
{
while(1)
{
recvnum = recv(socketfd,recvbuff,MAX,0);
if (recvnum > 0)
{
recvbuff[recvnum] = '\0';
std::cout << recvbuff << std::endl;
memset(recvbuff,0,sizeof(recvbuff));
}
}
}
char* Client::get_sendbuff()
{
return sendbuff;
}
void Client::close_socket()
{
close(socketfd);
}
int Client::get_sockfd()
{
return socketfd;
}
int main()
{
cout << "enter your name please:";
char name[10];
cin >> name;
char* psend;
Client socking;
psend = socking.get_sendbuff();
socking.created_socket();
if (socking.connect_socket() == -1)
{
return 0;
}
std::thread t1(&Client::recv_socket,&socking);
while(1)
{
cin.getline(psend,200);
if (psend[0] == 'q' && psend[1] == '\0')
{
break;
}
char s[MAX+20];
sprintf(s,"%s%s%s",name,":",psend);
if (socking.send_socket(socking.get_sockfd(),s) == -1)
{
std::cout << "send messages failed..." << std::endl;
return 0;
}
}
socking.close_socket();
t1.detach();
}
[C++] 纯文本查看 复制代码 #include <iostream>
//文件名: C_service.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string>
#include <thread>
#include <mutex>
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include <algorithm>
#include <map>
#include <set>
#define MAX 4096
using namespace std;
std::set<int> clientfd; //全局的set容器clientfd,存放不同客户端的connfd(句柄)
std::mutex mtx; //多线程的锁
class Service //服务端类
{
public:
Service();
~Service();
void created_socket(); //创建socket套接字
void bind_socket(); //绑定服务器端口用于监听和接收message
void listen_socket(); //监听端口
void accept_socket(); //接受客户端连接
void receive_socket(); //接收message
void close_socket(); //关闭套接字
private:
int socketfd; //定义套接字
int connfd; //定义一个accept的句柄,用于recv函数的参数
struct sockaddr_in ser_addr; //定义服务端地址的结构体
char recvbuff[MAX]; //接收的数据
int recvnum; //创建recv句柄
struct sockaddr_in client_addr; //定义客户端地址的结构体
int socketlen; //定义结构体长度(这个定义有点重复了)
int reuse; //定义端口重用
};
Service::Service()
{
socketfd = socket(AF_INET, SOCK_STREAM, 0); //套接字
memset((void*)&ser_addr,0,sizeof(ser_addr));
ser_addr.sin_family = AF_INET; //定义服务端地址
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ser_addr.sin_port = htons(7788);
socketlen = sizeof(struct sockaddr_in);
memset(recvbuff,0,sizeof(recvbuff));
reuse = 1;
setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)); //使端口可重用
}
Service::~Service()
{
}
void Service::created_socket()
{
if(socketfd == -1)
{
std::cout << "create socket error! " << std::endl;
}
else
{
std::cout << "create socket success..." << std::endl;
}
}
void Service::bind_socket()
{
if(bind(socketfd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) == -1)
{
std::cout << "bind socket error" << std::endl;
}
else
{
std::cout << "bind socket success..." << std::endl;
}
}
void Service::listen_socket()
{
if(listen(socketfd,10) == -1)
{
std::cout << "failed to listen the socket" << std::endl;
}
else
{
std::cout << "listen socket success..." << std::endl;
}
}
void Service::accept_socket()
{
connfd = accept(socketfd,(struct sockaddr*)&client_addr,(socklen_t*)&socketlen);
if(connfd == -1)
{
std::cout << "accept socket error" << std::endl;
}
else
{
std::cout << "connfd is " << connfd << std::endl;
std::cout << "accept socekt success" << std::endl;
}
mtx.lock(); //多线程的锁,避免多线程同时操作变量
clientfd.insert(connfd);
mtx.unlock();
}
void Service::receive_socket()
{
while(1)
{
recvnum = recv(connfd,recvbuff,MAX,0);
if(recvnum > 0)
{
set<int> i = clientfd;
recvbuff[recvnum] = '\0';
std::cout << recvbuff << std::endl;
if (i.size() > 0)
{
for (auto iter = i.begin();iter != i.end();++iter)
{
if (*iter == connfd)
{
continue;
}
send(*iter,recvbuff,sizeof(recvbuff),0);
}
}
}
else if(recvnum == 0)
{
break;
}
}
}
void thread_listen(Service s)
{
while(1)
{
s.listen_socket();
s.accept_socket();
s.receive_socket();
}
}
int main()
{
Service socking;
socking.created_socket();
socking.bind_socket();
std::thread t1(thread_listen,socking);
std::thread t2(thread_listen,socking);
std::thread t3(thread_listen,socking);
t1.join();
t2.join();
t3.join();
}
|
免费评分
-
查看全部评分
|