一、
用多程序實現為多個客戶服務的例子
在伺服器為每個客戶建立乙個程序,這個程序負責和客戶的通訊
fork()
子程序負責和客戶端的通訊,父程序負責監聽
二、
基於udp
程式設計
tcp提供面向連線的服務,保證資料傳輸的可靠性、傳輸資料的有序性、流量控制、全雙工
主要用於傳輸檔案 效率低
udp提供不面向連線的服務,不提供客戶機與伺服器的連線
步保證資料傳輸的可靠性 也是全雙工
a) 基於udp實現伺服器端
第一步:建立socket
第三步:recvfrom阻塞等待客戶端的請求
recvfrom(2)
#include
#include
ssize_trecvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr*src_addr, socklen_t *addrlen);
功能:從socket接受資料
引數:sockfd:socket(2)返回值
flags:0
返回值:
接收到的位元組數
-1表示錯誤
第四步:資料處理
第五步:給客戶端傳送應答資料
sendto(2)
#include
#include
ssize_tsendto(int sockfd, const void *buf, size_t len, int flags, const structsockaddr *dest_addr, socklen_t addrlen);
功能:通過socket傳輸資料
引數:sockfd:
buf:
b) 基於udp實現客戶端
第一步:建立乙個socket
第二步:直接給伺服器傳送資料請求
第三步:阻塞等待伺服器的應答
第四步:關閉檔案描述符
舉例:vi udpserv.c
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 int main(void)
18 bzero(&servaddr,sizeof(servaddr));
19 servaddr.sin_family=af_inet;
20 servaddr.sin_port=htons(4777);
21 servaddr.sin_addr.s_addr=htonl(inaddr_any);
22 //將s_fd和伺服器的位址繫結
23 bind(s_fd,(struct sockaddr *)&servaddr,sizeof(servaddr));
24 printf("bind...\n");
25 while(1)
33 for(int i=0;i34 buf[i]=toupper(buf[i]);
35 }
36 //傳送資料給客戶端
37 sendto(s_fd,buf,n,0,(struct sockaddr *)&cliaddr,\
38 sizeof(cliaddr));
39 }
40 return 0;
41 }
vi client.c
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 typedef struct sockaddr sa;
9 typedef struct sockaddr_in sa_i;
10 int main(void)
27 close(s_fd);
28 return 0;
29 }
tarena@tarena-virtual-machine:~/day34$gcc udpserv.c -o server -std=c99
tarena@tarena-virtual-machine:~/day34$gcc udpcli.c -o client -std=c99
在乙個終端開啟伺服器
tarena@tarena-virtual-machine:~/day34$./server
bind...
在另乙個終端開啟客戶端
tarena@tarena-virtual-machine:~/day34$./client
tang
tang
hello tang
hello tang
(輸入小寫,自動轉換大寫)
三、執行緒的基本概念
a) 什麼是執行緒?
執行緒是程式執行的基本單位
注意:
程序和執行緒的關係
程序是資源分配的基本單位。乙個程序可以同時擁有多個執行緒,即同時被系統排程的多條執行路線,但至少要有乙個主線程。程序中的所有執行緒共享程序的資源。
由於多個執行緒共享程序的資源,所以執行緒的切換的資源開銷遠遠小於程序的切換。
每個執行緒都有自己的執行緒號,成為tid。 thread
b) 建立執行緒
pthread_create(3)
#include
intpthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
compile and linkwith -pthread
功能:建立乙個新的執行緒
引數:thread:用於存放執行緒id
attr:null
start_routine:指向執行緒執行的函式的指標
arg:是第三個函式的引數
返回值:
0:成功
非0:失敗
pthread_self(3)
#include
pthread_tpthread_self(void);
功能:獲取這個執行緒自己的tid
返回值:返回執行緒的id
舉例:建立乙個執行緒。 thread.c
1 #include
2 #include
3 #include
4 #include
5 pthread_t tid;
6 void printids(const char *s)
11 //執行緒的執行函式
12 void *func(void *arg)
18 int main(void)tarena@tarena-virtual-machine:~/day34$ gccthread.c -lpthread -o thread
tarena@tarena-virtual-machine:~/day34$./thread
s=main thread
pid=3560 tid=3075634880
s=hello
pid=3560 tid=3075631936
若:17 pthread_create(&tid,null,func,"hello");
18 sleep(1);
19 printids("mainthread");
s=hello
pid=3671 tid=3075795776
s=main thread
pid=3671 tid=3075798720
主線程等了1s
執行緒的終止
不要使用exit退出程序
pthread_exit實現執行緒的退出
11 //執行緒的執行函式
12 void *func(void *arg)
8 void *th_fn2(void *arg)
12 int main(void)
建立了兩個子執行緒,加上主線程共有3個執行緒,join是主線程等待子執行緒
tarena@tarena-virtual-machine:~/day34$gcc join.c -lpthread -o join
tarena@tarena-virtual-machine:~/day34$./join
thread1returning...
thread1 exitcode 1
thread2 exit...
thread2 exitcode 2
如果 // 16 pthread_join(tid,&ret);
則:tarena@tarena-virtual-machine:~/day34$ ./join
thread1 exitcode -1217191948
thread2 exit...
thread1returning...
thread2 exitcode 2
UDP伺服器客戶端相互通訊
udp伺服器 客戶端之間的相互通訊 之前的版本只能實現udp伺服器之間單發單收,此版本能實現udp伺服器和客戶端之間的相互通訊。見下面的程式 udp server.c include include include include include include include define por...
UDP 客戶端伺服器
udp 客戶端 include include include include include define size 100 define ip 127.0.0.1 define port 10086 int main struct sockaddr in addr 建立socket udp so...
UDP實現伺服器和客戶端的通訊
一 服務端 include include include include include include include include include include include include include include include include include include ...