socket学习笔记——线程(聊天程序)
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学习笔记——线程(聊天程序)的更多相关文章
- java swing+socket实现多人聊天程序
swing+socket实现多人聊天程序 1.准备工作 先看效果: 客户端项目结构图: 服务端项目结构图: 2.运行原理 服务端 先开一个线程serverListerner,线程中开启一个Server ...
- JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?
前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...
- Android IPC机制(五)用Socket实现跨进程聊天程序
1.Socket简介 Socket也称作“套接字“,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信.它分为流式套接字和数据包套接 ...
- SYSBIOS学习笔记---线程(Threads)
在SYS/BIOS中,广义上指被处理器执行的任何独立的指令流.线程是一个能够调用一个函数或者中断服务程序的单点控制.在sysbios系统中一共有硬件中断(HWI).软件中断(SWI).任务(Task) ...
- Java Socket 学习笔记
TCP协议的Socket编程 Socket:英文中的意思是插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket.Java中所有关于网络编程的类都 ...
- [快手(AAuto)学习笔记]如何让程序在运行时请求管理员权限(UAC)
作者:ffsystem 作为(糟糕的)程序猿,习惯写代码解决一些简单事务.正常用批处理就能解决大部分工作,复杂一点用AutoIt 3. 有时候要分发给别人,就需要一个界面.外行你程序写得如何他看不懂, ...
- 微信小程序学习笔记一 小程序介绍 & 前置知识
微信小程序学习笔记一 1. 什么是小程序? 2017年度百度百科十大热词之一 微信小程序, 简称小程序, 英文名 Mini Program, 是一种不需要下载安装即可使用的应用 ( 张小龙对其的定义是 ...
- linux学习笔记:vim程序编辑器—vim的使用
注:以下是学习<鸟哥的linux私房菜>(第三版)的学习笔记,纯属个人学习记录. 2018-11-19 一.学习vim的原因 很多软件的编辑接口都会主动调用vi 二.vim的使用 (1)v ...
- Java学习笔记——线程
线程: 定义:线程是程序内的一个单一的顺序控制流程,也被称为“轻型进程(lightweight process)” 或“执行上下文(execution context )” 线程用于分隔任务 线程类似 ...
随机推荐
- mac 下使用wireshark监听网络上的数据
分三个步骤: 1.wireshark安装 wireshark运行需要mac上安装X11,mac 10.8的系统上默认是没有X11的.先去http://xquartz.macosfo ...
- svn 批量更新 bat脚本
由于有多个程序放在svn上管理,每天都要进入相应的目录进行svn 更新操作,现在写了一个简单的脚本进行批量自动更新. Code@echo off @echo ********************* ...
- Form_Form Builder国际化多语言开发(案例)
2014-05-06 Created By BaoXinjian
- SOA_环境安装系列1_Oracle SOA Suite11g安装总括(案例)
2015-01-01 Created By BaoXinjian
- AP_HZ Party和Supplier、Bank表关系详解
2014-06-26 Created By BaoXinjian
- vim 学习日志(1):剪切,复制,粘贴,删除,撤销
一:光标命令 左h 上j 下k 右l :goto n 表示跳转到文本的第n个字符 :n 表示跳到第n行 nG n为行数,该命令立即使光标跳到指定行:n为空,光标跳到文件最后一行. Ctrl+G ...
- html5 基本内容 摘自W3C
HTML5 教程(摘录自 W3C School) HTML 5 简介(HTML5 是下一代的 HTML) 什么是 HTML5? HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标 ...
- linux操作系统的分类及解释
什么是Linux? 也许很多人会不屑的说,Linux不就是个操作系统么.错!Linux不是一个操作系统,严格来讲,Linux只是一个操作系统中的内核.内核是什么?内核建立了计算机软件与硬件之间通讯的平 ...
- Objective-C: 字符串NSString与NSMutableString
字符串算是OC中非常重要和常用的一部分内容,OC中的字符串与我之前在学习C,C++,Java中的字符串有一定的不同,它非常类似于C++中容器的概念,但用法却与之还是有很大的不同,也许是因为OC的语法就 ...
- C语言位运算符及作用:与、或、异或、取反、左移和右移
一.& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0应用:(1)清零 若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数 ...