server.c

 #include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h> #define BUF_SIZE 100
#define MAX_CLNT 256 void *handle_clnt(void* arg);
void send_msg(char *msg,int len);
void error_handling(char* message); int clnt_cnt = ;
int clnt_socks[MAX_CLNT];
pthread_mutex_t mutx; int main(int argc,char* argv[])
{
int serv_sock,clnt_sock;
struct sockaddr_in serv_addr,clnt_addr;
int adr_sz;
pthread_t t_id; if(argc != )
{
printf("usage: %s <port>\n",argv[]);
exit();
} pthread_mutex_init(&mutx,NULL);
serv_sock = socket(PF_INET,SOCK_STREAM,);
memset(&serv_addr,,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[])); if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -)
error_handling("bind error");
if(listen(serv_sock,) == -)
error_handling("listen error"); while()
{
adr_sz = sizeof(clnt_addr);
clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&adr_sz); pthread_mutex_lock(&mutx);
clnt_socks[clnt_cnt++] = clnt_sock;
pthread_mutex_unlock(&mutx); pthread_create(&t_id,NULL,handle_clnt,(void*)&clnt_sock);
pthread_detach(t_id);
printf("connected client ip:%s \n",inet_ntoa(clnt_addr.sin_addr));
}
close(serv_sock);
return ;
} void* handle_clnt(void* arg)
{
int clnt_sock = *((int*)arg);
int str_len = ,i;
char msg[BUF_SIZE]; while((str_len = read(clnt_sock,msg,sizeof(msg))) != )
send_msg(msg,str_len);
pthread_mutex_lock(&mutx);
for(i = ;i < clnt_cnt;i++)
{
if(clnt_sock == clnt_socks[i])
{
while(i++ < clnt_cnt-)
clnt_socks[i] = clnt_socks[i+];
break;
}
}
clnt_cnt--;
pthread_mutex_unlock(&mutx);
close(clnt_sock);
return NULL;
} void send_msg(char* msg,int len)
{
int i;
pthread_mutex_lock(&mutx);
for(i = ;i < clnt_cnt;i++)
write(clnt_socks[i],msg,len);
pthread_mutex_unlock(&mutx);
}
void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit();
}

client.c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/socket.h> #define BUF_SIZE 200
#define NAME_SIZE 20 void *send_msg(void* arg);
void *recv_msg(void* arg);
void error_handling(char* message); char name[NAME_SIZE] = "[DEFAULT]";
char msg[BUF_SIZE];
int main(int argc,char* argv[])
{
int sock;
struct sockaddr_in serv_addr;
pthread_t send_thread,recv_thread;
void * thread_return; if(argc != )
{
printf("usage: %s <ip> <port> <name>\n");
exit();
} sprintf(name,"[%s]",argv[]);
sock = socket(PF_INET,SOCK_STREAM,); memset(&serv_addr,,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[]);
serv_addr.sin_port = htons(atoi(argv[])); if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -)
error_handling("connect error"); pthread_create(&send_thread,NULL,send_msg,(void*)&sock);
pthread_create(&recv_thread,NULL,recv_msg,(void*)&sock);
pthread_join(send_thread,&thread_return);
pthread_join(recv_thread,&thread_return);
close(sock);
return ;
} void* send_msg(void* arg)
{
int sock = *((int*)arg);
char name_msg[NAME_SIZE+BUF_SIZE];
while()
{
fgets(msg,BUF_SIZE,stdin);
if(!strcmp(msg,"q\n") || !strcmp(msg,"Q\n"))
{
close(sock);
exit();
}
sprintf(name_msg,"%s %s",name,msg);
write(sock,name_msg,strlen(name_msg));
}
return NULL;
} void* recv_msg(void* arg)
{
int sock = *((int*)arg);
char name_msg[BUF_SIZE+NAME_SIZE];
int str_len;
while()
{
str_len = read(sock,name_msg,NAME_SIZE+BUF_SIZE-);
if(str_len == -)
return (void*)-;
name_msg[str_len] = ;
fputs(name_msg,stdout);
}
return NULL;
} void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit();
}

socket学习笔记——线程(聊天程序)的更多相关文章

  1. java swing+socket实现多人聊天程序

    swing+socket实现多人聊天程序 1.准备工作 先看效果: 客户端项目结构图: 服务端项目结构图: 2.运行原理 服务端 先开一个线程serverListerner,线程中开启一个Server ...

  2. JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?

    前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...

  3. Android IPC机制(五)用Socket实现跨进程聊天程序

    1.Socket简介 Socket也称作“套接字“,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信.它分为流式套接字和数据包套接 ...

  4. SYSBIOS学习笔记---线程(Threads)

    在SYS/BIOS中,广义上指被处理器执行的任何独立的指令流.线程是一个能够调用一个函数或者中断服务程序的单点控制.在sysbios系统中一共有硬件中断(HWI).软件中断(SWI).任务(Task) ...

  5. Java Socket 学习笔记

    TCP协议的Socket编程 Socket:英文中的意思是插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket.Java中所有关于网络编程的类都 ...

  6. [快手(AAuto)学习笔记]如何让程序在运行时请求管理员权限(UAC)

    作者:ffsystem 作为(糟糕的)程序猿,习惯写代码解决一些简单事务.正常用批处理就能解决大部分工作,复杂一点用AutoIt 3. 有时候要分发给别人,就需要一个界面.外行你程序写得如何他看不懂, ...

  7. 微信小程序学习笔记一 小程序介绍 & 前置知识

    微信小程序学习笔记一 1. 什么是小程序? 2017年度百度百科十大热词之一 微信小程序, 简称小程序, 英文名 Mini Program, 是一种不需要下载安装即可使用的应用 ( 张小龙对其的定义是 ...

  8. linux学习笔记:vim程序编辑器—vim的使用

    注:以下是学习<鸟哥的linux私房菜>(第三版)的学习笔记,纯属个人学习记录. 2018-11-19 一.学习vim的原因 很多软件的编辑接口都会主动调用vi 二.vim的使用 (1)v ...

  9. Java学习笔记——线程

    线程: 定义:线程是程序内的一个单一的顺序控制流程,也被称为“轻型进程(lightweight process)” 或“执行上下文(execution context )” 线程用于分隔任务 线程类似 ...

随机推荐

  1. Understanding and Managing SMTP Virtual Servers

    Simple Mail Transfer Protocol (SMTP) Service Overview The Simple Mail Transfer Protocol (SMTP) servi ...

  2. MongoDB 3.0.6的主,从,仲裁节点搭建

    在MongoDB所在路径创建log和data目录mkdir logmkdir data 在data目录下 创建master.slaver.arbiter路径 mkdir master mkdir sl ...

  3. python (16) 如何在linux下安装lxml(pip安装,ubuntu下,centos下)

    首先需要明白lxml包依赖其他包,必须先安装其他包然后再安装lxml 安装python-pip:方便安装python的第三方包 [root@******/]# wget https://bootstr ...

  4. hadoop对于压缩文件的支持及算法优缺点

    hadoop对于压缩文件的支持及算法优缺点   hadoop对于压缩格式的是透明识别,我们的MapReduce任务的执行是透明的,hadoop能够自动为我们 将压缩的文件解压,而不用我们去关心. 如果 ...

  5. 查询oracle中所有用户信息

    1.查看所有用户:select * from dba_users;   select * from all_users;   select * from user_users; 2.查看用户或角色系统 ...

  6. unix 中 ps -ef命令详解

    ps -ef 查看正在活动的进程 ps -ef |grep abc 查看含有"abc"的活动进程 ps -ef |grep -v abc 查看不含abc的活动进程 1)ps a 显 ...

  7. PHP框架 Laravel Eloquent ORM 批量插入数据 && 批量更新目前没有

    foreach ($products as $v=>$a) { $count[] = array('product_name' => $a['name'], 'product_weight ...

  8. Yii2.0 多文件上传

    --------------------------------------------------------------------------------------------------- ...

  9. rsyncd.conf 文件

    uid = nobodygid = nobodymax connections = 10timeout = 60use chroot = noread only = falsepid file=/va ...

  10. js判断正整数

    var r = /^\+?[1-9][0-9]*$/; //判断正整数 r.test(str);