3、同步
3.1 互斥锁
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr)
int pthread_mutex_destroy(pthread_mutex_t *mutex)
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
3.2条件变量
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFERSIZE 16
typedef struct product{
int buff[BUFFERSIZE];
int readpos,writepos;
pthread_mutex_t lock;
pthread_cond_t notfull;
pthread_cond_t notempty;
}product;
product buffer;
void init(product *pro){
pthread_mutex_init(&pro->lock,NULL);
pthread_cond_init(&pro->notempty,NULL);
pthread_cond_init(&pro->notfull,NULL);
pro->readpos=0;
pro->writepos=0;
}
int get(product *pro){
int data;
pthread_mutex_lock(&pro->lock);
if(pro->readpos==pro->writepos){
pthread_cond_wait(&pro->notempty,&pro->lock);
}
data=pro->buff[pro->readpos];
pro->readpos++;
if(pro->readpos >= BUFFERSIZE){
pro->readpos=0;
}
pthread_cond_signal(&pro->notfull);
pthread_mutex_unlock(&pro->lock);
return data;
}
void *customer(void *arg){
int d;
while(1){
d=get(&buffer);
if(-1==d){
break;
}
else{
printf("--->%d\n",d);
}
}
return NULL;
}
void put(product *pro,int data){
pthread_mutex_lock(&pro->lock);
if((pro->writepos+1)%BUFFERSIZE==pro->readpos){
pthread_cond_wait(&pro->notfull,&pro->lock);
}
pro->buff[pro->writepos]=data;
pro->writepos++;
if(pro->writepos >= BUFFERSIZE){
pro->writepos=0;
}
pthread_cond_signal(&pro->notempty);
pthread_mutex_unlock(&pro->lock);
}
void *producter(void *arg){
int i;
for(i=0;i<20;i++){
printf("%d--->\n",i+1);
put(&buffer,i+1);
}
put(&buffer,-1);
return NULL;
}
int main(int argc, char const *argv[]){
pthread_t thc,thp;
void * retval=NULL;
int ret;
init(&buffer);
ret=pthread_create(&thp,NULL,producter,NULL);
ret=pthread_create(&thc,NULL,customer,NULL);
pthread_join(thc,&retval);
pthread_join(thp,NULL);
return 0;
}
网络编程(C/S)
一、简介
struct in_addr{
unsigned long s_addr;
}
struct sockaddr_in{
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
}
地址转换与字节序转换
int inet_aton(const char *cp,struct in_addr *inp)
char *inet_ntoa(struct in_addr in)
unsigned long ip=inet_addr("192.168.1.1");
#include<arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
函数
#include <sys/socket.h>
int socket(int family, int type, int protocol);
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
int listen(int sockfd,int backlen);
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
int send(int sockfd,void *buf,size_t len,int flags)
int recv(int sockfd,void *buf,size_t len,int flags)
int sendto(int sockfd,void *buf,size_t len,int flags,struct sockaddr *toaddr,int tolen);
int recvfrom(int sockfd,void *buf,size_t len,int flags,struct sockaddr *fromaddr,int *fromlen);
二、TCP(建立连接)
1、循环服务器
1、S
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 8000
int main(int argc, char const *argv[])
{
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 1024);
int clilen;
int i=0;
char message[100];
int n_recv;
while(1)
{
clilen = sizeof(servaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
while (1)
{
n_recv = recvfrom(connfd, message, 100, 0, (struct sockaddr *)&cliaddr, &clilen);
if (0 == n_recv)
{
printf("client is offonlie!\n");
break;
}
for (i = 0; i < n_recv; i++)
{
message[i] = toupper(message[i]);
}
sendto(connfd, message, n_recv, 0, (struct sockaddr *)&cliaddr, sizeof(servaddr));
}
close(connfd);
}
close(listenfd);
return 0;
}
2、C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8000
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("need server IP!\n");
exit(0);
}
int sockfd;
struct sockaddr_in servaddr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(PORT);
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
char sendline[100];
char recvline[100];
int n_recv;
while(1)
{
fgets(sendline, 100, stdin);
sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
n_recv = recvfrom(sockfd, recvline, 100, 0, NULL, NULL);
recvline[n_recv] = '\0';
printf("recv %d char!\n", n_recv);
fputs(recvline, stdout);
}
close(sockfd);
return 0;
}
2、并发服务器(进程)
1、S
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
#define PORT 8000
void *func(void *arg)
{
int n_recv;
char message[100];
int i;
struct sockaddr_in servaddr, cliaddr;
int connfd;
connfd = *(int *)arg;
socklen_t clilen;
clilen = sizeof(cliaddr);
while (1)
{
n_recv = recvfrom(connfd, message, 100, 0, (struct sockaddr *)&cliaddr, &clilen);
if (0 == n_recv)
{
printf("client is offonlie!\n");
pthread_exit(NULL);
}
for (i = 0; i < n_recv; i++)
{
message[i] = toupper(message[i]);
}
sendto(connfd, message, n_recv, 0, (struct sockaddr *)&cliaddr, sizeof(servaddr));
}
close(connfd);
return NULL;
}
int main(int argc, char const *argv[])
{
int listenfd, connfd;
socklen_t clilen;
struct sockaddr_in servaddr, cliaddr;
pthread_t tid;
int ret;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 1024);
while (1)
{
clilen = sizeof(servaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
ret = pthread_create(&tid, NULL, func, (void *)&connfd);
}
close(listenfd);
return 0;
}
2、C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#define PORT 8000
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("need server IP!\n");
exit(0);
}
int sockfd;
struct sockaddr_in servaddr;
char sendline[100];
char recvline[100];
int n_recv;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(PORT);
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
while(1)
{
fgets(sendline, 100, stdin);
sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
n_recv = recvfrom(sockfd, recvline, 100, 0, NULL, NULL);
recvline[n_recv] = '\0';
printf("recv %d char!\n", n_recv);
fputs(recvline, stdout);
}
close(sockfd);
return 0;
}
3、并发服务器(线程)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
#define PORT 8000
void *func(void *arg)
{
int connfd = *(int *)arg;
int real_recv;
char recv[100];
struct sockaddr_in cliaddr;
int clilen;
while (1)
{
clilen = sizeof(cliaddr);
real_recv = recvfrom(connfd, recv, 100, 0, (struct sockaddr *)&cliaddr, &clilen);
if (real_recv == 0)
{
printf("client offonline!\n");
break;
}
sendto(connfd, recv, real_recv, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
}
close(connfd);
return NULL;
}
int main(int argc, char const *argv[])
{
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
int clilen;
pthread_t tid;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero((struct sockaddr *)&servaddr, sizeof(servaddr));
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_family = AF_INET;
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 1024);
while (1)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
pthread_create(&tid, NULL, func, (void *)&connfd);
}
close(listenfd);
return 0;
}
4、三次握手
三、UDP(无连接)
1、S
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 8000
int main(int argc, char const *argv[])
{
int listenfd;
struct sockaddr_in servaddr, cliaddr;
listenfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
int clilen;
int i=0;
char message[100];
int n_recv;
clilen = sizeof(servaddr);
while(1)
{
n_recv = recvfrom(listenfd, message, 100, 0, (struct sockaddr *)&cliaddr, &clilen);
for (i = 0; i < n_recv; i++)
{
message[i] = toupper(message[i]);
}
sendto(listenfd, message, n_recv, 0, (struct sockaddr *)&cliaddr, sizeof(servaddr));
}
close(listenfd);
return 0;
}
2、C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8000
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("need server IP!\n");
exit(0);
}
int sockfd;
struct sockaddr_in servaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(PORT);
char sendline[100];
char recvline[100];
int n_recv;
while(1)
{
fgets(sendline, 100, stdin);
int addrlen=sizeof(servaddr);
sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, addrlen);
n_recv = recvfrom(sockfd, recvline, 100, 0, (struct sockaddr *)&servaddr, &addrlen);
recvline[n_recv] = '\0';
printf("recv %d char!\n", n_recv);
fputs(recvline, stdout);
}
close(sockfd);
return 0;
}