这几天一直在看TCP/IP这块的内容,写个简单socket通信demo,实现了多个客户端相互发送消息,以及服务端给多个客户端发送上线/下线消息

基本框架:

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>#define PORT 6666
#define NUM_MAX_WAIT 1
#define NUM_MAX_CHAT 2typedef struct Message {bool type;  // 0: system  1: clientchar buff[1024];char name[30];
}Message;typedef struct Client {bool c_flage;int  c_fd;
}Client;int sockfd = 0;
int num_chat = 0;
bool quit = false;
pthread_t ptid[2] = {};
Client client[4] = {};void* pthread_comm(void* argc)
{Client* cli_com = argc;Message msg = {};int ret = recv(cli_com->c_fd, &msg, sizeof(msg), 0); if(0 == strlen(msg.buff) && 0 < strlen(msg.name)) {//printf("name:%s fd:%d flage:%d num_chat:%d\n", name_tmp, cli_com->c_fd, cli_com->c_flage, num_chat);bzero(&msg.buff, sizeof(msg.buff));msg.type = 0;sprintf(msg.buff, "==========[%s] 已进入聊天室[%d人] ==========", msg.name, num_chat);for(int i=0; i< NUM_MAX_CHAT; i++) {if(client[i].c_flage == true)send(client[i].c_fd, &msg, sizeof(msg), 0);    }}while(1) {bzero(&msg, sizeof(msg));int ret = recv(cli_com->c_fd, &msg, sizeof(msg), 0);   if(ret > 0 ) {   if((strcmp("quit", msg.buff)) == 0) {num_chat--;cli_com->c_flage = false;msg.type = 0;//printf("name:%s fd:%d flage:%d num_chat:%d\n", msg.name, cli_com->c_fd, cli_com->c_flage, num_chat);sprintf(msg.buff, "==========[%s] 已退出聊天室[%d人] ==========", msg.name, num_chat);for(int i=0; i< NUM_MAX_CHAT; i++) {if(client[i].c_flage == true)send(client[i].c_fd, &msg, sizeof(msg), 0);  }bzero(&msg, sizeof(msg));break;}else {//printf("recver:%s by %s\n", msg.buff, msg.name);msg.type = 1;for(int i=0; i<NUM_MAX_CHAT; i++) {if(client[i].c_flage == true)send(client[i].c_fd, &msg, sizeof(msg), 0);}}}}pthread_exit(NULL);
}void* pthread_accept(void *argc)
{struct sockaddr_in client_sk;socklen_t client_len = sizeof(struct sockaddr_in);bzero(&client_sk, sizeof(client_sk));printf("========== 聊天室已创建 ==========\n");while(1) {if(NUM_MAX_CHAT > num_chat) {int i ;for(i=0; i< NUM_MAX_CHAT; i++) {if(client[i].c_flage == false) {client[i].c_fd = accept(sockfd, (struct sockaddr*)&client_sk, &client_len);client[i].c_flage = true;    printf("client[%d] fd:%d flage:%d chat_num:%d\n", i, client[i].c_fd, client[i].c_flage, num_chat);break;}}num_chat++;if((pthread_create(&ptid[1], NULL, pthread_comm, &client[i])) !=0 ){perror("pthread comm create");pthread_exit(NULL);}}}pthread_exit(NULL);
}int main(char argc, char *argv)
{struct sockaddr_in serv_sk;if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {perror("Create socket");exit(1);}bzero(&serv_sk, sizeof(serv_sk));serv_sk.sin_family = AF_INET;serv_sk.sin_port   = htons(PORT); serv_sk.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(sockfd, (struct sockaddr *)&serv_sk, sizeof(serv_sk)) == -1) {perror("Bind socke");exit(1);}listen(sockfd, NUM_MAX_WAIT);if(pthread_create(&ptid[0], NULL, pthread_accept, NULL) != 0) {perror("pthread accept create");pthread_exit(NULL);}  while(!quit);close(sockfd);
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/socket.h>
#include <string.h>#define PORT 6666
#define MAX_BUFF 1024typedef struct Message {bool type;   //0: system 1:clientchar buff[MAX_BUFF];char name[30];
}Message;Message send_msg = {};
Message recv_msg = {};
int sockfd = 0;
bool quit = false;void* pthread_recv(void* argc)
{while(1) {bzero(&recv_msg.buff, sizeof(recv_msg.buff));int ret = recv(sockfd, &recv_msg, sizeof(recv_msg), 0);if(0 < strlen(recv_msg.buff)) {if(recv_msg.type)printf("%s: %s\n", recv_msg.name, recv_msg.buff);elseprintf("%s\n", recv_msg.buff);}}close(sockfd);
}void* pthread_send(void* argc)
{send_msg.type = 0;send(sockfd, &send_msg, sizeof(send_msg), 0);while(1) {bzero(&send_msg.buff, sizeof(send_msg.buff));send_msg.type = 1;gets(send_msg.buff);printf("\33[1A");printf("\r                                             \r");if(0 < strlen(send_msg.buff)) {//printf("%s send:%s\n", send_msg.name, send_msg.buff);send(sockfd, &send_msg, sizeof(send_msg), 0);if(!strcmp("quit", send_msg.buff)) {quit = true;break;}}}
}int main(char argc, char* argv)
{pthread_t ptid[2] = {};struct sockaddr_in client_sk;if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) ==-1) {perror("Create socket");exit(1);}bzero(&client_sk, sizeof(struct sockaddr_in));client_sk.sin_family = AF_INET;client_sk.sin_port = htons(PORT);client_sk.sin_addr.s_addr = htonl(INADDR_ANY);    if((connect(sockfd, (struct sockaddr*)&client_sk, sizeof(struct sockaddr))) == -1) {perror("Connect server");exit(1);}bzero(&send_msg, sizeof(send_msg));printf("请输入您的昵称:");scanf("%s", send_msg.name);if((pthread_create(&ptid[0], NULL, pthread_recv, NULL)) != 0) {perror("pthread create recv");pthread_exit(NULL);}if((pthread_create(&ptid[1], NULL, pthread_send, NULL)) !=0) {perror("pthread create send");pthread_exit(NULL);        }while(!quit);close(sockfd);
}

Makefile

all:gcc -o client client.c -lpthreadgcc -o server server.c -lpthread

运行服务端

运行客户端A,昵称:刘备

运行客户端B,昵称:关羽

基于Linux下TCP/IP协议局域网聊天室相关推荐

  1. java毕业设计——基于java+TCP+UDP的局域网聊天室系统设计与实现(毕业论文+程序源码)——局域网聊天室系统

    基于java+TCP+UDP的局域网聊天室系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+TCP+UDP的局域网聊天室系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地 ...

  2. 基于UDP/IP协议的聊天室

    基于TCP/IP通信协议的聊天室 概述: 基于TCP/IP通信协议的聊天室是通过服务端/客户端的模式进行的,必须是服务端开启之后,客户端通过获取服务端的ip和端口号并连接之后才能进行信息的共享,具体的 ...

  3. linux中tcp/ip协议实现及嵌入式应用 下载,LINU中TCPIP协议实现及嵌入式应用

    好文网为大家准备了关于LINU中TCPIP协议实现及嵌入式应用范文,好文网里面收集了五十多篇关于好LINU中TCPIP协议实现及嵌入式应用好文,希望可以帮助大家.更多关于LINU中TCPIP协议实现及 ...

  4. 基于C#的TCP/IP协议应用(一)

    一.背景与概念 1.标准以太网 以太网是美国Xerox(施乐)公司的Palo Alto研究中心于1975年研制成功的,其核心技术起源于ALOHA网.目前以太网是指符合IEEE 802.3标准的局域网( ...

  5. Linux下TCP/IP优化

    在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握 ...

  6. Linux --OSI TCP/IP协议族

    OSI简介 简介 OSI Open System Interconnection 开放系统互联模型 开放式系统互联 国际标准化组织(ISO)制定 定义了不同计算机互联的标准 设计和描述,计算机网络通信 ...

  7. 回顾下TCP/IP协议

    首先要知道什么是TCP/IP协议,从字面意思来看TCP是"Transmission Control Protocol"的缩写,也就是传输控制协议.IP是"Internet ...

  8. Linux下Select多路复用实现简易聊天室

    前言 和之前的udp聊天室有异曲同工之处,这次我们客户端send的是一个封装好了的数据包,recv的是一个字符串,服务器recv的是一个数据包,send的是一个字符串,在用户连接的时候发送一个logi ...

  9. linux tcp ip c,Linux下TCP/IP编程--TCP实战(select)

    本文参考自徐晓鑫<后台开发>,记录之. 一.为什么要使用非阻塞I/O之select 初学socket的人可能不爱用select写程序,而习惯诸如connect.accept.recv/re ...

最新文章

  1. 2021-10-11 二叉树中查找值为key的结点
  2. 数字三角形问题 (动态规划初步)
  3. C# 网络编程之通过ip地址获取地理位置(补充)
  4. OpenFOAM流固耦合问题-FsiFoam(foam-extend-4.0)运行tutorials的bug修复
  5. 华为防火墙Edumon1000E配置
  6. react16.8+的生命周期
  7. 大数据分块_谷歌卫星影像金字塔分块下载原理说明
  8. HDU2795 billboard【转化为线段树。】
  9. java留言板_java实现简单留言板功能的代码实例
  10. 【vue源码工程阅读1:下载源码】认识工程并打包
  11. YML解析框架SnakeYaml简介
  12. 《心经》-翻译、中英梵对照
  13. msdn原版系统和原版office
  14. k8s节点NotReady问题定位
  15. 2021-01-30
  16. 数据结构与算法笔记:贪心策略之BSTBBST, Hashtable+Dictionary+Map, Priority Queue~Heap, Minium Spanning Tree
  17. 家庭版Windows10/Windows11不支持远程桌面的解决办法
  18. 组合拳砸来:55位权威专家论剑股市!
  19. 如何区别药品的通用名、商品名(品牌名)和别名?
  20. CNI-Terway讲解

热门文章

  1. C++模拟与高精度——生活大爆炸版石头剪刀布
  2. 王权富贵:查看Linux的Python安装路径
  3. 苹果android是什么,如果用苹果最新的芯片运行安卓系统会是什么情况?
  4. Docker监控软件CAdvisor(免费)
  5. 童装业务占比扩大,APS生产排产解决服装企业生产管理难题
  6. border 0.5 IOS兼容问题
  7. background属性详解
  8. Android9.0访问不到服务器或者无法加载图片
  9. 标准POE供电及网线的8芯作用
  10. 联想i微型计算机怎么拆,联想B325I一体机怎么拆