0
点赞
收藏
分享

微信扫一扫

Linux多线程网络通讯CS模型,终端输入触发read

史值拥 2022-05-15 阅读 150

服务端

Linux环境Ubuntu18.04

经测试发现当服务端第20行代码将套接字设为不存在的套接字,则可以从服务端的终端输入字符,read(不存在的套接字,buffer,sizeof(buffer))终端输入的触发,粗略测试值为0,1,2支持这种场景,有些值则不可以,只能推测有些套接字是系统自带的

#include <pthread.h>
#include <sys/mutex>
int clnt_socks[100]{};
int clnt_cnt = 0;
pthread_mutex_t mutex;
void send_msg(const char* msg, int str_len)
{
for (int i = 0; i < clnt_cnt; i++) {
pthread_mutex_lock(&mutex);
if(clnt_socks[i] >= 0 )
write(clnt_socks[i], msg, str_len);
pthread_mutex_unlock(&mutex);
}
}
void* handle_clnt(void* arg)
{
printf("%s(%d):%s\n", __FILE__, __LINE__, __FUNCTION__);
pthread_detach(pthread_self());
int clnt_sock = *(int*)arg;
clnt_sock = 0;//测试过0,1,2
char msg[1024];
int str_len;
std::cout << "connect client sock value = " << clnt_sock << std::endl;
while ((str_len = read(clnt_sock, msg, sizeof(msg))) > 0)
{
std::cout<<"read from terminal message:"<<msg<<std::endl;
send_msg(msg, str_len);
}
pthread_mutex_lock(&mutex);
*(int*)arg = -1;
pthread_mutex_unlock(&mutex);
close(clnt_sock);
pthread_exit(NULL);
}

void server98()
{
printf("%s(%d):%s\n", __FILE__, __LINE__, __FUNCTION__);
int serv_sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
socklen_t clnt_adr_sz = sizeof(sockaddr_in);
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(9527);
int optval = 1;
setsockopt(AF_INET, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(sockaddr));//开启端口复用
pthread_mutex_init(&mutex, NULL);
if (bind(serv_sock, (sockaddr*)&serv_adr, sizeof(sockaddr))) {
printf("bind errno:%d %s\n", errno, strerror(errno));
return;
}
if (listen(serv_sock, 5)) {
printf("listen error %d %s\n", errno, strerror(errno));
}
for (;;) {
clnt_sock = accept(serv_sock, (sockaddr*)&clnt_adr, &clnt_adr_sz);
if (clnt_sock == -1) {
printf("accept error %d %s\n", errno, strerror(errno));
break;
}
pthread_mutex_lock(&mutex);
clnt_socks[clnt_cnt++] = clnt_sock;
pthread_mutex_unlock(&mutex);
pthread_t thread;
pthread_create(&thread, NULL, handle_clnt, clnt_socks + clnt_cnt - 1);
}
close(serv_sock);
pthread_mutex_destroy(&mutex);
}

void lession98(const char * arg)
{
if (strcmp(arg, "s") == 0) {
server98();
}
else
{
client98();
}
}


int main(int argc,char *argv[])
{
lession98(argv[1]);
}

客户端

void* recvserver(void* arg)
{
printf("%s(%d):%s\n", __FILE__, __LINE__, __FUNCTION__);
pthread_detach(pthread_self());
int sock = *(int*)arg;
char msg[1024];
int msg_len;
while ((msg_len = read(sock, msg, sizeof(msg))) > 0)
{
msg[msg_len] = 0;
std::cout << msg << std::endl;
}
pthread_exit(NULL);
}
void client98() {
pthread_t thread;
int sock = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in serv_adr;
serv_adr.sin_family = AF_INET;
serv_adr.sin_port = htons(9527);
serv_adr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sock, (sockaddr*)&serv_adr, sizeof(serv_adr));
pthread_create(&thread, NULL, recvserver, &sock);
char msg[1024];
while (true) {
std::cin >> msg;
if (write(sock, msg, strlen(msg)) > 0);
else
break;
}
std::cout << "客户端退出" << std::endl;
}
举报

相关推荐

0 条评论