Liunx C 编程之多线程与Socket
多线程pthread.h是linux特有的头文件,POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版pthreads-win32。 创建线程 pthread_create (threadid,attr,start_routine,arg) 结束线程 2.如果main()在其他线程创建前用pthread_exit()退出了,其他线程将会继续执行。否则,他们会随着main的结束而终止。 pthread_exit (status) int pthread_cancel(pthread_t threadid); 等待线程状态 pthread_join (threadid,status) 例子: 1 #include <stdio.h> 2 #include <pthread.h> //liunx线程头文件 3 #include <stdlib.h> 4 线程 5 void *thread1_proc(void *arg) 6 { 7 int i=*(int *)arg; 取出内容 8 free(arg);释放空间 9 while(i<105) 10 { 11 printf("thread1:%-5d",i); 12 sleep(2);延时等待两秒 13 i++; 14 } 15 printf(Thread1 finished!n); 16 pthread_exit(NULL);终止当前线程 17 } 18 void main() 19 20 pthread_t thread1; 21 int *ixi=(int *)malloc(sizeof(int));在堆中申请一块内容 22 *ixi=100; 存在内容 23 if(pthread_create(&thread1,NULL,thread1_proc,(void *)ixi)!=0)创建线程1并传递参数 24 perror(Create thread Failed:");创建错误时执行 25 终止当前线程,此时会子线程会执行完毕,相当于在此处join所有子线程一样 26 pthread_exit(NULL);(1)结束主 27 pthread_join(thread1,NULL);(2)可替换上一条 28 printf(主线程已经退出,本条不执行"); (1)不执行,(2)执行该条 29 } 多线程共享资源共享资源时可能会出现操作未完成而被另一个线程打破,造成资源存取异常 #include <pthread.h>
pthread_mutex_t lockx;
初始化 pthread_mutex_init(&lockx,NULL); 上锁与解锁 pthread_mutex_lock(&lockx);上锁 独立资源 代码块 pthread_mutex_unlock(&lockx);解锁 信号量 #include <semaphore.h>
sem_t can_scanf;
初始化 sem_init(&can_scanf,0,1)">1);
PV操作 sem_wait(&can_scanf);等待信号量置位并进行减一操作 sem_post(&can_scanf); 信号量加一 操作 例子 2 #include <semaphore.h> 3 #include <pthread.h> 4 #include <stdlib.h> 5 sem_t can_add;能够进行加法计算的信号量 6 sem_t can_mul;能够进行输入的信号量 7 sem_t can_scanf;能够进行乘法计算的信号量 8 int x,y; 9 void *thread_add(void *arg)加法线程入口函数 11 while(112 13 sem_wait(&can_add); 14 printf(%d+%d=%dn",x,y,x+y); 15 sem_post(&can_mul); 16 void *thread_mul(乘法线程入口函数 20 21 22 sem_wait(&23 printf(%d*%d=%dn24 sem_post(&can_scanf); 25 26 27 28 29 pthread_t tid; 30 int arg[2]; 31 信号量初始化 32 sem_init(&can_scanf,1)">33 sem_init(&can_add,1)">034 sem_init(&can_mul,1)">35 if(pthread_create(&tid,thread_add,NULL)<36 37 printf(Create thread_add Failed!n38 exit(39 40 41 42 printf(Create thread_mul Failed!n43 exit(44 45 46 47 sem_wait(&can_scanf);等待信号量置位并进行减一操作 48 printf(Please input two integers:49 scanf(%d%d50 sem_post(&can_add);信号量加一 操作 51 } 52 } Socket编程数据包的发送
TCP服务端 3、 Bind socket信息 设置server的详情信息 struct sockaddr_in server_addr,client_addr; u32_t sock_size= sockaddr_in); server_addr.sin_family = AF_INET; IPV4 server_addr.sin_port = htons(2351); 端口 绑定本机的所有IP地址htonl(INADDR_ANY),确定某个inet_addr(“172.16.4.1”) server_addr.sin_addr.s_addr =htonl(INADDR_ANY); bind(connect_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)); 4、 listen确定请求队列的最大值 5、 accept等待接入 6、 send ? 7、 recv 客户端 绑定本机的所有IP地址htonl(INADDR_ANY),确定某个inet_addr(“172.16.4.1”) server_addr.sin_addr.s_addr = inet_addr(192.168.43.21); int ret=connect(client_fd,sock_size);连接服务器 4、recv 和 send ?服务器示例 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <sys/socket.h> 5 #include <arpa/inet.h> 6 #include <netinet/in.h> 7 #include <string.h> #define MAXCONN 8 listen_fd,comm_fd; 12 ret; 13 int i=14 15 int sock_size= sockaddr_in); 16 listen_fd=socket(AF_INET,SOCK_STREAM,1)">0);创建一个socket,参数(IPV4,TCP,0) 17 if(listen_fd<19 perror(Failed to create socket:20 return -22 bzero(&server_addr,1)">清零server_addr 23 server_addr.sin_family=AF_INET;IPV4 24 server_addr.sin_port=htons(8000);端口 25 server_addr.sin_addr.s_addr=INADDR_ANY;绑定主机全部网络地址 26 setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&i,1)">设置套接字关联的选 项 27 ret=bind(listen_fd,1)">网络主机绑定 28 if(ret==30 printf(Bind Successfully!n31 32 ret=listen(listen_fd,MAXCONN);确定最大监听数 33 34 35 printf(Listen Successfully!n37 while((comm_fd=accept(listen_fd,1)">struct sockaddr*)&client_addr,&sock_size))>=阻塞并等待接入 38 39 char ipaddr[1640 inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ipaddr,1)">16);网络地址符转换 41 printf(连接进入:%sn42 43 { 44 char buff[51245 count; 46 count=read(comm_fd,buff,1)">511);读数据,接收 47 if(count>判断接收的字节数是否大于零 48 { 49 buff[count]=0;截断字符串 50 printf(收到来自 %s 的数据:%sn51 if(strncmp(buff,1)">quit4)==判断退出条件 52 { 53 printf(%s已经退出退出,等待下一个连接n54 break;退出此个连接,进行下一个连接接入 55 } 56 write(comm_fd,count);写数据,发送 57 } 58 else 59 60 printf(A talking is over!n61 break; //客户端断开 62 63 } 64 65 close(listen_fd);关闭连接 66 return 67 68 } 客户端示例 8 #include <int main(int argc,1)">char **argv) client_fd; sockaddr_in server_addr; char buf[16 char recv_buf[18 if(argc<20 printf(Usage:./client serveripn21 22 23 bzero(&server_addr,1)">24 client_fd=socket(AF_INET,1)">25 server_addr.sin_family=AF_INET; 26 server_addr.sin_port=htons(800027 server_addr.sin_addr.s_addr=inet_addr(argv[]); 28 ret=connect(client_fd,1)">连接服务器 29 if(ret<30 31 perror(Failed to connect:32 33 34 printf(Connect successfully!n36 { printf(请输入要发送的内容:37 fgets(buf,1)">512,stdin);从键盘获取字符串 38 ret=write(client_fd,buf,strlen(buf));if(ret<=40 41 if(strncmp(buf,1)">){ 42 printf(程序退出n43 ; 45 count=read(client_fd,recv_buf,1)">46 47 48 recv_buf[count]=截断接收的字符串 49 printf(Echo:%sn50 } 51 53 ;//服务器断开 54 56 close(client_fd);57 58 59 } UDP服务器 int setsockopt(int s,1)">int level,1)">int optname,1)">const optval,socklen_t optlen); 头文件:<sys/socket.h> level : 选项级别(例如SOL_SOCKET) optname : 选项名(例如SO_BROADCAST) optval : 存放选项值的缓冲区的地址 optlen : 缓冲区长度 返回值:成功返回0 失败返回-1并设置errno 3、 绑定服务器信息bind int sendto(int sockfd,1)">void *msg,size_t len,1)">int flags,1)">struct sockaddr *to,1)"> tolen); 返回:大于0-成功发送数据长度;--出错; UDP套接字使用无连接协议,因此必须使用sendto函数,指明目的地址; msg:发送数据缓冲区的首地址; len:缓冲区的长度; flags:传输控制标志,通常为0; to:发送目标; tolen: 地址结构长度——struct sockaddr) 数据接收 int recvfrom(void *buf,1)">struct sockaddr *from,1)">int *fromlen); 返回:大于0——成功接收数据长度;-——出错; buf:接收数据的保存地址; len:接收的数据长度 flags:是传输控制标志,通常为0; from:保存发送方的地址 fromlen: 地址结构长度。 服务器示例 1 #include <sys/socket.h> 2 #include <netinet/ 3 #include <arpa/inet.h> 4 #include < 5 #include <stdio.h> 7 sockfd; 10 15 sockfd=socket(AF_INET,SOCK_DGRAM,1)">if(sockfd<18 perror(Failed to socket:19 21 bzero(&server_addr,sock_size); 22 server_addr.sin_family=AF_INET;服务器相关参数设置 23 server_addr.sin_port=htons(600024 server_addr.sin_addr.s_addr=INADDR_ANY; 25 setsockopt(sockfd,1)">)); 26 if(bind(sockfd,sock_size)<等待客户端接入,阻塞 28 perror(Failed to bind:29 32 33 ret=recvfrom(sockfd,&sock_size);收到数据包 34 if(ret>35 36 buff[ret]=37 inet_ntop(AF_INET,1)">38 printf(Receive a string from %s:%d,data:%sn39 exit0){退出 40 printf(Socket server exit 41 close(sockfd);关闭socket 42 44 sendto(sockfd,ret,1)">struct sockaddr*)&client_addr,1)">45 close(sockfd); 48 } 客户端示例 8 #include <strings.h> Usage:./udpclient serveripn23 client_fd=socket(AF_INET,1)">24 bzero(& { In:31 fgets(buf,stdin); 32 ret=sendto(client_fd,strlen(buf),1)">33 35 perror(Failed to sendto:36 37 38 40 count=recvfrom(client_fd,1)">struct sockaddr*)&sock_addr,1)">sock_size); 42 43 recv_buf[count]=44 printf(48 perror(Failed to recvfrom:49 close(client_fd); 53 54 55 } 参考: https://www.cnblogs.com/mywolrd/archive/2009/02/05/1930707.html 物联网网关开发技术(罗老师) (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |