Linux开发——系统编程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_25490573/article/details/101988329

目录

exec函数族:

fork创建新进程

无名管道man 7 pipe:

消息队列:

信号:

信号量:

共享内存:

套接字:

线程用法:


exec函数族:

man 3 exec     说明 实例如下:

– “l”和“v”表示参数是以列表还是以数组的方式提供的

– “p”表示这个函数的第一个参数是*path,就是以绝对路径来提供程序的

路径,也可以以当前目录作为目标

– “e”表示为程序提供新的环境变量

#include<stdio.h> 
#include<string.h>
#include<stdlib.h>
#include <unistd.h>

//exec函数族
int main(void)
{
	if(execl("/mnt/udisk/helloexec","helloexec","execl",NULL) == -1){
		perror("execl error");
		exit(1);
	}
	//程序已经跳转走,如果正常execl不反回错误,下面的代码不会执行!
	printf("execl error!\n");
	return 0;
}

fork创建新进程

pid_t fork(void);  返回子进程的id号 

#include <stdio.h>
#include <unistd.h>

main()
{
	pid_t pid;
	int i=100;
	
	pid = fork();
	//调用出错
	if(pid == -1){
		printf("fork failed\n");
		return 1;
	}
	//返回给父进程子进程号,返回值大于0
	else if(pid){
		i++;
		printf("\nThe father i = %d\n",i);
		printf("The father return value is %d\n",pid);
		printf("The father pid is %d\n",getpid());
		printf("The father ppid is %d\n",getppid());
		while(1);
	}
	//返回子进程0,返回值等于0返回给子进程
	else{
		i++;
		printf("\nThe child i = %d\n",i);
		printf("The child return value is %d\n",pid);
		printf("The child pid is %d\n",getpid());
		printf("The child ppid is %d\n",getppid());
		while(1);
	}
	return 0;
}

无名管道man 7 pipe:

int pipe(int pipefd[2])

– 参数pipefd[0]:用于读管道

– 参数pipefd[1]:用于写管道

– 返回值:执行成功返回0,失败返回-1

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

//进程读函数
void read_data(int *);
//进程写函数 
void write_data(int *);


int main(int argc,char *argv[])
{
	int pipes[2],rc;
	pid_t pid;
		
	rc = pipe(pipes);	//创建管道                 
	if(rc == -1){
		perror("\npipes\n");
		exit(1);
	}
		
	pid = fork();	//创建进程 

	switch(pid){
		case -1:
			perror("\nfork\n");
			exit(1);
		case 0:
			read_data(pipes);	//相同的pipes
		default:
			write_data(pipes);	//相同的pipes
	}	
	return 0;
}

//进程读函数
void read_data(int pipes[])
{
	int c,rc;
	
	//由于此函数只负责读,因此将写描述关闭(资源宝贵)
	close(pipes[1]);
	
	//阻塞,等待从管道读取数据
	//int 转为 unsiged char 输出到终端
	while( (rc = read(pipes[0],&c,1)) > 0 ){  		
		putchar(c);       		                       
	}

	exit(0);
}

//进程写函数
void write_data(int pipes[])
{
	int c,rc;

	//关闭读描述字
	close(pipes[0]);                          

	while( (c=getchar()) > 0 ){
		rc = write( pipes[1], &c, 1);	//写入管道
		if( rc == -1 ){
			perror("Parent: write");
			close(pipes[1]);
			exit(1);
		}
	}

	close( pipes[1] );
	exit(0);
}

有名管道man 3 mkfifo:

• int mkfifo(const char *pathname, mode_t mode)

– 参数*pathname:路径名,管道名称

– 参数mode:管道的权限

– 返回值:成功返回0,错误返回-1

创建

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void filecopy(FILE *,char *);

int main(void)
{
	FILE *fp1;
	long int i = 100000;
	char buf[] = "I want to study Linux!\n";
	char *file1 = "data.txt";
	
	printf("begin!\n");
	
	if((fp1 = fopen(file1,"a+")) == NULL ){
			printf("can't open %s\n",file1);
	}
	while(i--)
	filecopy(fp1,buf);

	fclose(fp1);
	
	printf("over!\n");
	
	return 0;
}

void filecopy(FILE *ifp,char *buf)
{
	char c;
	int i,j;
	j = 0;
	i = strlen(buf)-1;	
	while(i--){
		putc(buf[j],ifp);
		j++;
	}
	putc('\n',ifp);
}

读取

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <fcntl.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <limits.h>  
#include <string.h>  
  
int main()  
{  
    const char *fifo_name = "my_fifo";  
    int pipe_fd = -1;  
    int data_fd = -1;  
    int res = 0;  
    int open_mode = O_RDONLY;  
    char buffer[PIPE_BUF + 1];  
    int bytes_read = 0;  
    int bytes_write = 0;  
    //清空缓冲数组  
    memset(buffer, '\0', sizeof(buffer));  
  
    printf("Process %d opening FIFO O_RDONLY\n", getpid());  
    //以只读阻塞方式打开管道文件,注意与fifowrite.c文件中的FIFO同名  
    pipe_fd = open(fifo_name, open_mode);  
    //以只写方式创建保存数据的文件  
    data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644);  
    printf("Process %d result %d\n",getpid(), pipe_fd);  
  
    if(pipe_fd != -1)  
    {  
        do  
        {  
            //读取FIFO中的数据,并把它保存在文件DataFormFIFO.txt文件中  
            res = read(pipe_fd, buffer, PIPE_BUF);  
            bytes_write = write(data_fd, buffer, res);  
            bytes_read += res;  
        }while(res > 0);  
        close(pipe_fd);  
        close(data_fd);  
    }  
    else  
        exit(EXIT_FAILURE);  
  
    printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);  
    exit(EXIT_SUCCESS);  
} 

写入:

#include <unistd.h>  
#include <stdlib.h>  
#include <fcntl.h>  
#include <limits.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <stdio.h>  
#include <string.h>  
  
int main()  
{  
    const char *fifo_name = "my_fifo";
	char *file1 = "data.txt";	
    int pipe_fd = -1;  
    int data_fd = -1;  
    int res = 0;  
    const int open_mode = O_WRONLY;  
    int bytes_sent = 0;  
    char buffer[PIPE_BUF + 1];  
  
    if(access(fifo_name, F_OK) == -1)  
    {  
        //管道文件不存在  
        //创建命名管道  
        res = mkfifo(fifo_name, 0777);  
        if(res != 0)  
        {  
            fprintf(stderr, "Could not create fifo %s\n", fifo_name);  
            exit(EXIT_FAILURE);  
        }  
    }  
  
    printf("Process %d opening FIFO O_WRONLY\n", getpid());  
    //以只写阻塞方式打开FIFO文件,以只读方式打开数据文件  
    pipe_fd = open(fifo_name, open_mode);  
    data_fd = open(file1, O_RDONLY);  
    printf("Process %d result %d\n", getpid(), pipe_fd);  
  
    if(pipe_fd != -1)  
    {  
        int bytes_read = 0;  
        //向数据文件读取数据  
        bytes_read = read(data_fd, buffer, PIPE_BUF);  
        buffer[bytes_read] = '\0';  
        while(bytes_read > 0)  
        {  
            //向FIFO文件写数据  
            res = write(pipe_fd, buffer, bytes_read);  
            if(res == -1)  
            {  
                fprintf(stderr, "Write error on pipe\n");  
                exit(EXIT_FAILURE);  
            }  
            //累加写的字节数,并继续读取数据  
            bytes_sent += res;  
            bytes_read = read(data_fd, buffer, PIPE_BUF);  
            buffer[bytes_read] = '\0';  
        }  
        close(pipe_fd);  
        close(data_fd);  
    }  
    else  
        exit(EXIT_FAILURE);  
  
    printf("Process %d finished\n", getpid());  
    exit(EXIT_SUCCESS);  
} 

消息队列:

函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long

msgtyp,int msgflg)

– 参数msqid:消息队列的标识码

– 参数*msgp:指向消息缓冲区的指针

– 参数msgsz:消息的长短

– 参数msgflg:标志位

– 返回值:成功返回数据长度,错误返回-1

• 函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int

msgflg)

– 参数msqid:消息队列的标识码

– 参数*msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收

的消息,是一个用户可定义的通用结构

– 参数msgsz:消息的长短

– 参数msgflg:标志位

– 返回值:成功返回0,错误返回-1

• 结构体msgp,是一个标准的通用结构

– struct msgstru{

long mtype; //大于0

char mtext[nbyte];}

• 函数int msgget(key_t key, int msgflg)

– 参数“key”:消息队列关联的标识符

– 参数“msgflg”:消息队列的建立标志和存取权限。IPC_CREAT 如果内核

中没有此队列则创建它;IPC_EXCL 当和IPC_CREAT 一起使用时,如果

队列已经存在,则失败

– 返回值:执行成功则返回消息队列的标识符,否则返回-1

• 函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long

msgtyp,int msgflg)

– 参数msgtyp

• msgtyp等于0 ,则返回队列的最早的一个消息

• msgtyp大于0,则返回其类型为mtype的第一个消息

• msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消

– 参数msgflg:标志位为0,则表示忽略

发送例子

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <sys/msg.h>  
#include <errno.h>  
  
#define MAX_TEXT 512  
struct msg_st  
{  
    long int msg_type;  
    char text[MAX_TEXT];  
};  
  
int main()
{  
    int running = 1;  
    struct msg_st data;  
    char buffer[BUFSIZ];  
    int msgid = -1;  
  
    //建立消息队列  
    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
    if(msgid == -1)  
    {  
        fprintf(stderr, "msgget failed with error: %d\n", errno);  
        exit(EXIT_FAILURE);  
    }  
  
    //向消息队列中写消息,直到写入end  
    while(running)  
    {  
        //输入数据  
        printf("Enter some text: ");  
        fgets(buffer, BUFSIZ, stdin);  
        data.msg_type = 1;    //注意2  
        strcpy(data.text, buffer);  
        //向队列发送数据  
        if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
        {  
            fprintf(stderr, "msgsnd failed\n");  
            exit(EXIT_FAILURE);  
        }  
        //输入end结束输入  
        if(strncmp(buffer, "end", 3) == 0)  
            running = 0;  
        sleep(1);  
    }  
    exit(EXIT_SUCCESS);  
}

接受例子

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <errno.h>  
#include <sys/msg.h>  
  
struct msg_st
{  
    long int msg_type;  
    char text[BUFSIZ];  
};  
  
int main()  
{  
    int running = 1;  
    int msgid = -1;  
    struct msg_st data;  
    long int msgtype = 0; //注意1  
  
	
  
    //建立消息队列  
    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
    if(msgid == -1)  
    {  
        fprintf(stderr, "msgget failed with error: %d\n", errno);  
        exit(EXIT_FAILURE);  
    }  
    //从队列中获取消息,直到遇到end消息为止  
    while(running)  
    {  
        if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
        {  
            fprintf(stderr, "msgrcv failed with errno: %d\n", errno);  
            exit(EXIT_FAILURE);  
        }  
        printf("You wrote: %s\n",data.text);  
        //遇到end结束  
        if(strncmp(data.text, "end", 3) == 0)  
            running = 0;  
    }  
    //删除消息队列  
    if(msgctl(msgid, IPC_RMID, 0) == -1)  
    {  
        fprintf(stderr, "msgctl(IPC_RMID) failed\n");  
        exit(EXIT_FAILURE);  
    }  
    exit(EXIT_SUCCESS);  
} 

信号:

• unsigned int alarm(unsigned int seconds)

– 参数seconds:闹钟的时间,单位为秒

– 返回值:成功返回0 或者返回剩余时间;错误返回-1

• sighandler_t signal(int signum, sighandler_t handler);

– 参数signum:等待的信号

– 参数handler:信号到来之后,触发的处理方式

– 返回值:成功返回0,错误返回-1

简单例子:

#include<unistd.h>
#include<stdio.h>
#include<signal.h>

void handler()
{
	printf("hello\n");
}

int main(void)
{
	int i;
	signal(SIGALRM,	handler);
	alarm(5);
	
	for(i=1;i<7;i++){
		printf("sleep %d....\n",i);
		sleep(1);
	}
	
	return 0;
}

复杂例子

#include <unistd.h>  
#include <signal.h>  
#include <sys/types.h>  
#include <stdlib.h>  
#include <stdio.h>  

void handler(int sig)  
{  
    printf("Handler the signal %d\n", sig);  
}  
  
int main(void)  
{  
    sigset_t sigset;//用于记录屏蔽字  
    sigset_t ign;//用于记录被阻塞的信号集  
    struct sigaction act; 
	
    //清空信号集  
    sigemptyset(&sigset);  //初始化信号集
    sigemptyset(&ign);  
    //向信号集中添加信号SIGINT  
    sigaddset(&sigset, SIGINT);  
  
    //设置处理函数和信号集      
    act.sa_handler = handler;  
    sigemptyset(&act.sa_mask);  
    act.sa_flags = 0;  
    sigaction(SIGINT, &act, 0);  
  
    printf("Wait the signal SIGINT...\n");  
    pause();//挂起进程,等待信号  
  
    //设置进程屏蔽字,在本例中为屏蔽SIGINT   
    sigprocmask(SIG_SETMASK, &sigset, 0);     
    printf("Please press Ctrl+c in 10 seconds...\n");  
    sleep(10); 
	
    //测试SIGINT是否被屏蔽  
    sigpending(&ign);  
	
    if(sigismember(&ign, SIGINT))  
        printf("The SIGINT signal has ignored\n"); 
	
    //在信号集中删除信号SIGINT  
    sigdelset(&sigset, SIGINT);  
    printf("Wait the signal SIGINT...\n"); 
	
    //将进程的屏蔽字重新设置,即取消对SIGINT的屏蔽  
    //并挂起进程  
    sigsuspend(&sigset);  
  
    printf("The app will exit in 5 seconds!\n");  
    sleep(5);  
    exit(0);  
}

信号量:

例子:

#include <unistd.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <sys/sem.h>  
  
union semun  
{  
    int val;  
    struct semid_ds *buf;  
    unsigned short *arry;  
};  
  
static int sem_id = 0;  
  
static int set_semvalue();  
static void del_semvalue();  
static int semaphore_p();  
static int semaphore_v();  
  
int main(int argc, char *argv[])  
{  
    char message = 'X';  
    int i = 0;  
  
    //创建信号量  
    sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);  
  
    if(argc > 1)  
    {  
        //程序第一次被调用,初始化信号量  
        if(!set_semvalue())  
        {  
            fprintf(stderr, "Failed to initialize semaphore\n");  
            exit(EXIT_FAILURE);  
        }  
        //设置要输出到屏幕中的信息,即其参数的第一个字符  
        message = argv[1][0];  
        sleep(2);  
    }  
    for(i = 0; i < 10; ++i)  
    {  
        //进入临界区  
        if(!semaphore_p())  
            exit(EXIT_FAILURE);  
        //向屏幕中输出数据  
        printf("%c", message);  
        //清理缓冲区,然后休眠随机时间  
        fflush(stdout);  
        sleep(rand() % 3);  
        //离开临界区前再一次向屏幕输出数据  
        printf("%c", message);  
        fflush(stdout);  
        //离开临界区,休眠随机时间后继续循环  
        if(!semaphore_v())  
            exit(EXIT_FAILURE);  
        sleep(rand() % 2);  
    }  
  
    sleep(10);  
    printf("\n%d - finished\n", getpid());  
  
    if(argc > 1)  
    {  
        //如果程序是第一次被调用,则在退出前删除信号量  
        sleep(3);  
        del_semvalue();  
    }  
    exit(EXIT_SUCCESS);  
}  
  
static int set_semvalue()  
{  
    //用于初始化信号量,在使用信号量前必须这样做  
    union semun sem_union;  
  
    sem_union.val = 1;  
    if(semctl(sem_id, 0, SETVAL, sem_union) == -1)  
        return 0;  
    return 1;  
}  
  
static void del_semvalue()  
{  
    //删除信号量  
    union semun sem_union;  
  
    if(semctl(sem_id, 0, IPC_RMID, sem_union) == -1)  
        fprintf(stderr, "Failed to delete semaphore\n");  
}  
  
static int semaphore_p()  
{  
    //对信号量做减1操作,即等待P(sv)  
    struct sembuf sem_b;  
   sem_b.sem_num = 0;  
    sem_b.sem_op = -1;//P()  
    sem_b.sem_flg = SEM_UNDO;  
    if(semop(sem_id, &sem_b, 1) == -1)  
    {  
        fprintf(stderr, "semaphore_p failed\n");  
        return 0;  
    }  
    return 1;  
}  
  
static int semaphore_v()  
{  
    //这是一个释放操作,它使信号量变为可用,即发送信号V(sv)  
    struct sembuf sem_b;  
    sem_b.sem_num = 0;  
    sem_b.sem_op = 1;//V()  
    sem_b.sem_flg = SEM_UNDO;  
    if(semop(sem_id, &sem_b, 1) == -1)  
    {  
        fprintf(stderr, "semaphore_v failed\n");  
        return 0;  
    }  
    return 1;  
}

共享内存:

写入例子

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <sys/shm.h>  
#include "shmdata.h"  
  
int main(void)  
{  
    int running = 1;//程序是否继续运行的标志  
    void *shm = NULL;//分配的共享内存的原始首地址  
    struct shared_use_st *shared;//指向shm  
    int shmid;//共享内存标识符  
    //创建共享内存  
    shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);  
    if(shmid == -1)  
    {  
        fprintf(stderr, "shmget failed\n");  
        exit(EXIT_FAILURE);  
    }  
    //将共享内存连接到当前进程的地址空间  
    shm = shmat(shmid, 0, 0);  
    if(shm == (void*)-1)  
    {  
        fprintf(stderr, "shmat failed\n");  
        exit(EXIT_FAILURE);  
    }  
    printf("\nMemory attached at %p\n", shm);  
    //设置共享内存  
    shared = (struct shared_use_st*)shm;  
    shared->written = 0;  
    while(running)//读取共享内存中的数据  
    {  
        //没有进程向共享内存定数据有数据可读取  
        if(shared->written != 0)  
        {  
            printf("You wrote: %s", shared->text);  
            sleep(rand() % 3);  
            //读取完数据,设置written使共享内存段可写  
            shared->written = 0;  
            //输入了end,退出循环(程序)  
            if(strncmp(shared->text, "end", 3) == 0)  
                running = 0;  
        }  
        else//有其他进程在写数据,不能读取数据  
            sleep(1);  
    }  
    //把共享内存从当前进程中分离  
    if(shmdt(shm) == -1)  
    {  
        fprintf(stderr, "shmdt failed\n");  
        exit(EXIT_FAILURE);  
    }  
    //删除共享内存  
    if(shmctl(shmid, IPC_RMID, 0) == -1)  
    {  
        fprintf(stderr, "shmctl(IPC_RMID) failed\n");  
        exit(EXIT_FAILURE);  
    }  
    exit(EXIT_SUCCESS);  
}

读取例子:

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <sys/shm.h>  
#include "shmdata.h"  
  
int main(void)  
{  
    int running = 1;  
    void *shm = NULL;  
    struct shared_use_st *shared = NULL;  
    char buffer[BUFSIZ + 1];//用于保存输入的文本  
    int shmid;  
    //创建共享内存  
    shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);  
    if(shmid == -1)  
    {  
        fprintf(stderr, "shmget failed\n");  
        exit(EXIT_FAILURE);  
    }  
    //将共享内存连接到当前进程的地址空间  
    shm = shmat(shmid, (void*)0, 0);  
    if(shm == (void*)-1)  
    {  
        fprintf(stderr, "shmat failed\n");  
        exit(EXIT_FAILURE);  
    }  
    printf("Memory attached at %p\n", shm);  
    //设置共享内存  
    shared = (struct shared_use_st*)shm;  
    while(running)//向共享内存中写数据  
    {  
        //数据还没有被读取,则等待数据被读取,不能向共享内存中写入文本  
        while(shared->written == 1)  
        {  
            sleep(1);  
            printf("Waiting...\n");  
        }  
        //向共享内存中写入数据  
        printf("Enter some text: ");  
        fgets(buffer, BUFSIZ, stdin);  
        strncpy(shared->text, buffer, TEXT_SZ);  
        //写完数据,设置written使共享内存段可读  
        shared->written = 1;  
        //输入了end,退出循环(程序)  
        if(strncmp(buffer, "end", 3) == 0)  
            running = 0;  
    }  
    //把共享内存从当前进程中分离  
    if(shmdt(shm) == -1)  
    {  
        fprintf(stderr, "shmdt failed\n");  
        exit(EXIT_FAILURE);  
    }  
    sleep(2);  
    exit(EXIT_SUCCESS);  
}

套接字:

tcp服务器端:

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
	int sfp, nfp, num = 0;
	struct sockaddr_in s_add,c_add;
	int sin_size;
	unsigned short portnum=0x8888;

	char buffer[100] = {0};

	printf("Hello,welcome to my server !\r\n");

    //其他协议可以设置socket(AF_INET,SOCK_RAW,1...111);
    //htons()htonl()本地转网络 ntohs ntohl网络转本地 
    //inet_ntoa(u32) 无符号转为点分十进制
	sfp = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sfp)
	{
			printf("socket fail ! \r\n");
			return -1;
	}

	printf("socket ok !\r\n");

	bzero(&s_add,sizeof(struct sockaddr_in));
	s_add.sin_family=AF_INET;
	s_add.sin_addr.s_addr=htonl(INADDR_ANY);
	s_add.sin_port=htons(portnum);

	if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
	{
			printf("bind fail !\r\n");
			return -1;
	}

	printf("bind ok !\r\n");

	if(-1 == listen(sfp,5))
	{
			printf("listen fail !\r\n");
			return -1;
	}

	printf("listen ok\r\n");



			sin_size = sizeof(struct sockaddr_in);

			nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size);
			if(-1 == nfp)
			{
					printf("accept fail !\r\n");
					return -1;
			}

			printf("accept ok!\r\nServer start get connect from %#x : %#x\r\n", 
									ntohl(c_add.sin_addr.s_addr), ntohs(c_add.sin_port));
			while(1)
			{
					memset(buffer, 0, 100);
					sprintf(buffer, "hello,welcome to my server(%d) \r\n", num++);
					send(nfp, buffer, strlen(buffer), 0);
					usleep(500000);
			}


			close(nfp);


	close(sfp);

	return 0;
}

tcp客户端:

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char **argv)
{
	int cfd;
	int recbyte;
	int sin_size;
	char buffer[1024] = {0};

	struct sockaddr_in s_add, c_add;
	unsigned short portnum = 0x8888;

	printf("Hello,welcome to client!\r\n");

	if(argc != 2)
	{
			printf("usage: echo ip\n");
			return -1;
	}

	cfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == cfd)
	{
			printf("socket fail ! \r\n");
			return -1;
	}

	printf("socket ok !\r\n");

	bzero(&s_add,sizeof(struct sockaddr_in));
	s_add.sin_family=AF_INET;
	s_add.sin_addr.s_addr= inet_addr(argv[1]);
	s_add.sin_port=htons(portnum);
	printf("s_addr = %#x ,port : %#x\r\n",s_add.sin_addr.s_addr,s_add.sin_port);

	if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
	{
			printf("connect fail !\r\n");
			return -1;
	}

	printf("connect ok !\r\n");

	while(1)
	{
			if(-1 == (recbyte = read(cfd, buffer, 1024)))
			{
					printf("read data fail !\r\n");
					return -1;
			}

			printf("read ok\r\nREC:\r\n");
			buffer[recbyte]='\0';
			printf("%s\r\n",buffer);
	}

	close(cfd);

	return 0;

}

udp服务器端:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char **argv)
{
	int n;
	char recvline[1024] = {0};

	int sockfd;
	struct sockaddr_in servaddr;

	/* 创建一个UDP连接的socket */
	sockfd = socket(PF_INET, SOCK_DGRAM, 0);

	/* 变量servaddr清零 */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);	
	servaddr.sin_port = htons(50001);

	/* 绑定servaddr到创建的socket上 */
	bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

	/* 接收客户端发送的数据 */
	recvfrom(sockfd, recvline, 1024, 0, NULL, NULL);

	printf("%s\n", recvline);

	/* 关闭socket连接 */
	close(sockfd);
}

udp客户端:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char **argv)
{
	int sockfd;
	struct sockaddr_in servaddr;

	if(argc != 2)
	{
			printf("usgae: ./client [ip]\n");

			return -1;
	}

	/* 创建一个UDP的socket连接 */
	sockfd = socket(PF_INET, SOCK_DGRAM, 0);

	/* 变量servaddr清零 */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(50001);
	servaddr.sin_addr.s_addr = inet_addr(argv[1]);

	char sendline[100];
	sprintf(sendline, "Hello, world!");

	/*  发送数据 */
	sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));

	/* 关闭socket连接 */
	close(sockfd);

	return 1;
}

线程用法:

#include <stdio.h>
#include <pthread.h>

void * thread01(void * arg)
{
        int a = 0;
        printf("thread01 pid is :%u\n",pthread_self());
        for(;a<1000;){
                a += 66;
        }
        printf("thread01 result is: %d,pid is:%u\n",a,pthread_self());
        return NULL;
}
void * thread02(void * arg)
{
        int a = 0;
        printf("thread02 pid is :%u\n",pthread_self());
        for(;a<1000;){
                a += 66;
        }
        printf("thread02 result is: %d,pid is:%u\n",a,pthread_self());
        return NULL;
}

int main(int args,char*argv[]){

        pthread_t t1,t2;
        pthread_create(&t1,NULL,thread01,NULL);
        pthread_create(&t2,NULL,thread02,NULL);

        pthread_join(t1,NULL);
        pthread_join(t2,NULL);

        return 0;


}
//编译时需要加上 -pthread

猜你喜欢

转载自blog.csdn.net/qq_25490573/article/details/101988329
今日推荐