输入参数
int main(int argc,char **argv);
argc代表输入参数个数+1
argv代表输入参数数组
argv[0]代表当前可执行文件的名称
argv[1]代表第一个输入参数
标准IO
用于读写普通文件
//打开文件
FILE *fopen(const char *pathname, const char *type)
//临时文件
FILE *tmpfile(void)
//格式化输出
int fprintf(FILE *fp, const char *format, ...)
//格式化输出到缓冲区
int sprintf(char *buf, const char *format, ...)
//读文件
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
//从指定流中读一行
char *fgets(char *str, int n, FILE *stream)
//文件位置偏移
int fseek(FILE *stream, long int offset, int whence)
//写文件
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
//关闭文件
int fclose(FILE *stream)
//常用流
stdin 标准终端输入流
stdout 标准终端输出流
#include <stdio.h>
#include <errno.h>
#define N 64
int main(int argc,const char *argv[])
{
FILE *fps,*fpd;
int n;
char buf[N];
if (argc < 3) {
printf("Usage:%s <src_file> <dst_file>\n",argv[0]);
return -1;
}
/*打开源文件和目标文件*/
if ((fps = fopen(argv[1],"r")) == NULL) {
perror("fopen");
return -1;
}
if ((fpd = fopen(argv[2],"w+")) == NULL) {
perror("fopen");
return -1;
}
/*读写流*/
while ((n = fread(buf,1,N,fps)) > 0) { /*当n接收到的字符数小于0时,表示已经读取到文件的末尾*/
fwrite(buf,1,n,fpd);
}
fclose(fps);
fclose(fpd);
return 0;
}
文件IO
用于读写设备文件、管道等
//打开文件
int fd=open(char *name,int how);
/* name:设备路径和名称
* how: 权限: O_RDONLY 只读
* O_WRONLY 只写
* O_CREAT 创建
*/
//读文件
read(int fd,const void *buf,size_t count);
//写文件
write(int fd,const void *buf,size_t count);
//关闭文件
close(int fd);
多进程
原型
pid_t fork( void);
返回值: 成功调用一次会有两个返回值, 子进程返回0, 父进程返回子进程ID; 出错返回-1
Note:
进程创建成功后,父进程以及子进程都从fork()之后开始执行,只是PID不同,fork语句可以看成讲程序切为A,B两个部分.(fock()成功之后,子进程克隆了父进程的所有变量,环境变量,程序计数器的当前空间和值)
结束进程
使用exit()函数 头文件 #include
使用_exit()函数 头文件 #include 区别: exit()结束进程会刷新缓冲区, _exit()不会
回收进程
用来回收资源处理僵尸进程
- 使用wait()函数回收进程
原型: pid_t wait(int *status) 成功返回子进程的进程号, 失败返回-1, wait()是阻塞直至某个子进程终止
- 使用waitpid()函数回收进程
原型: pid_t waitpid(pid_t pid, int *status, int options); 成功返回子进程的进程号,失败返回-1
僵尸进程
僵尸进程是父进程未结束, 但子进程结束了,但仍然保留一些信息等待父进程回收资源,但父进程没有使用wait/waitpid回收子进程资源导致的,当父进程结束后会回收僵尸进程资源。 使用这个信号signal(SIGCHLD,SIG_IGN); 父进程提前死亡,子进程会交给init进程,当子进程死亡后init进程会回收子进程资源避免成为僵尸进程
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t fpid;
printf("hello fork\n");
fpid = fork();
if (fpid < 0)
printf("error fork\n");
else if (fpid == 0)
printf("I am the child process, my pid is %d , my parent pid is%d\n",
getpid() ,getppid());
else
printf("I am the parent process, my pid is %d\n",getpid());
return 0;
}
/* result:
* hello fork
* I am the parent process, my pid is 3361
* I am the child process, my pid is 3362 , my parent pid is 3361
*/
//结果只看到一次hello fork, 因为子进程克隆了父进程的程序计数器,只执行fork()后的内容
进程通信
消息队列
接口
//头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//创建/打开消息队列
int msgget(key_t key,int flag);
/* key: 和消息队列关联的key
* flag: 访问权限
* 返回值: 成功返回消息队列ID, 失败返回-1
*/
//控制消息队列
int msgctl(int msgqid,int cmd, struct msqid_ds *buf);
/* msgqid: 消息队列id
* cmd: IPC_STAT: 读取消息队列属性,结果保存在buf
* IPC_SET: 设置消息队列属性
* IPC_RMID: 删除消息队列
*/
//添加一条消息到消息队列
int msgsnd(int msgqid, const void *msgp,size_t size,int flag);
/* msgid:消息队列id
* msgp:指向消息的指针
* struct msgbuf {
* long mtype; //消息类型
* char mtext[N]; //消息正文
* };
* size:消息正文的字节数
* flag: IPC_NOWAIT: 非阻塞
* 0: 阻塞
*/
//从消息队列接收一条消息
int msgrcv(int msgqid,void *msgp,size_t size,long msgtype,int flag);
/* msgqid:消息队列id
* msgq:接收消息缓冲区
* size:要接收消息的字节数
* msgtype: 0:接收消息队列中的第一个消息
* 大于0: 接收消息队列中第一个类型为msgtype的消息
* 小于0: 接收消息对垒中类型值不大于msgtype的绝对值且类型又最小的消息
* flag: IPC_NOWAIT:非阻塞
* 0:阻塞
*/
server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <signal.h>
#include <string>
struct msgbuf {
long type; //消息类型
char voltage[124]; //消息正文
}
int main(int argc, char **argv[])
{
int msgid,readret,key;
struct msgbuf sendbuf;
key = ftok(".",1);
if (key < 0)
{
printf("create key fail\n");
return -1;
}
msgid = msgget(key,IPC_CREAT|0777);
if (msgid<0)
{
printf("create msg queue fail\n");
return -1;
}
printf("create msg queue success, msgid=%d\n",msgid);
system("ipcs -q");
sendbuf.type = 100;
while(1)
{
memset(sendbuf.voltage,0,124);
printf("please input message:");
fgets(sendbuf.voltage,124,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.voltage),0);
}
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <signal.h>
#include <string.h>
struct msgbuf {
long type; //消息类型
char voltage[124]; //消息正文
};
int main(int argc,char **argv[])
{
int msgid,key;
struct msgbuf readbuf;
key = ftok(".",1);
if (key<0)
{
printf("create key fail\n");
return -1;
}
msgid = msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
printf("create msg queue fail\n");
return -1;
}
printf("create msg queue success,msgid=%d\n",msgid);
system("ipcs -q");
while(1)
{
memset(readbuf.voltage,0,124);
msgrcv(msgid,(void *)&readbuf,124,100,0);
}
return 0;
}
共享内存
共享内存没有同步和互斥机制, 使用时需要配合信号量来实现共享内存存取的同步
接口
/* 头文件 */
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/>
/* 生成Key */
key_t ftok(const char *pathname, int proj_id);
/* pathname: 指定的文件名,文件一定要存在
* proj_id: 0~255,可以自行约定
*/
/* 创建共享内存 */
int shmget(key_t key,int size,int shmflg);
/* key: IPC_PRIVATE(用于子父进程)或ftok()的返回值
* size: 共享内存区大小
* shmflg: 权限位, 创建使用IPC_CREAT, 已存在使用IPC_EXCL
* 返回值: 成功返回共享内存的ID, 失败返回-1
*/
/* 操作共享内存 */
int shmctl(int shm_id,int cmd,struct shmid_ds *buf);
/* shm_id: shmget返回的ID
* cmd: IPC_STAT : 用共享内存的当前关联值覆盖shmid_ds的值
* IPC_SET: 共享内存的当前关联值设置为shmid_ds结构中给出的值
* IPC_RMID: 删除共享内存段
* buf: 共享内存模式和访问权限的结构指针
*/
/* 将共享内存映射到用户空间 */
void *shmat(int shm_id,const void *shm_addr,int shmflg);
/* shm_id: shmget返回的ID
* shm_addr: 指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址
* shmflg: 一组标志位,通常为0
* 返回值: 返回映射后的内存地址
*/
/* 解除地址映射,该操作不删除标志符和数据结构 */
int shmdt(const void *shmaddr);
/* shmaddr: shmat返回的地址
*/
client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
typedef struct
{
int size;
char content[0];
}shm_buf;
int main(int argc, char const *argv[])
{
int shmid;
int key;
shm_buf *p;
key = ftok("/",1);
if (key<0){
printf("create key fail\n");
return -1;
}
printf("create key success key=0x%X\n",key);
shmid = shmget(key,128,IPC_CREAT|0777);
if(shmid<0){
printf("create shared memory fail\n");
return -1;
}
printf("create shared memory success ,shmid=%d\n",shmid);
system("ipcs -m");
p = (shm_buf *)shmat(shmid,NULL,0);
if(p == NULL){
printf("shmat fail\n");
return -1;
}
printf("shmat success\n");
while(1)
{
printf("input message: ");
fgets(p->content,128,stdin);
p->size = strlen(p->content);
printf("share memory data:%s\n", p->content);
}
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
typedef struct
{
int size;
char content[0];
}shm_buf;
int main(int argc, char const *argv[])
{
int shmid;
int key;
shm_buf *p;
key = ftok("/",1);
if (key<0){
printf("create key fail\n");
return -1;
}
printf("create key success key=0x%X\n",key);
shmid = shmget(key,128,IPC_CREAT|0777);
if(shmid<0){
printf("create shared memory fail\n");
return -1;
}
printf("create shared memory success ,shmid=%d\n",shmid);
system("ipcs -m");
p = (shm_buf *)shmat(shmid,NULL,0);
if(p == NULL){
printf("shmat fail\n");
return -1;
}
while(1)
{
if (p->size>0){
printf("shm buf:%s\n", p->content);
p->size = 0;
}
}
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
管道
无名管道
面向子父进程间的通信,实际上是一个单向队列, 在一端读,另一端写
+----+-----+-----+
fd[0]| | | | fd[1]
read ----> | | | | <---write
+----+-----+-----+
/* 创建 */
#include <unistd.h>
int pipe(int fd[2]);
/* 管道文件描述符 fd[0]为读端, fd[1]为写端
* 返回值0为成功,返回值1为失败
*/
/* 读 */
read(fd[0],readbuf,size);
/* 写 */
write(fd[1],writebuf,size);
/* 关闭 */
close(fd)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, int **argv[])
{
int fd[2];
pid_t fpid;
int ret = 0;
char write_buf[] = "hello pipe";
char read_buf[128] = {0};
ret = pipe(fd);
if (ret < 0)
{
printf("pipe error\n");
return -1;
}
printf("create pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
fpid = fork();
if (fpid < 0)
{
printf("error fork\n");
}
else if (fpid == 0)
{
read(fd[0],read_buf,sizeof(read_buf));
printf("read_buf=%s\n",read_buf);
close(fd[0]);
}
else
{
write(fd[1],write_buf,sizeof(write_buf));
close(fd[1]);
}
return 0;
}
有名管道
可用于任何进程间通信, 在内核上表现为一个文件, 进程通过文件IO操作读写信息 int mkfifo(const char *filename, mode_t mode ); 成功返回0, 失败返回-1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char **argv[])
{
int ret,fd;
char write_buf[] = "hello pipe";
if (access("./testPipe",0)<0)
{
ret = mkfifo("./testPipe",0777);
if(ret<0)
{
printf("create pipe fail\n");
return -1;
}
}
fd = open("./testPipe",O_WRONLY);
if (fd<0)
{
printf("open pipe fail");
return -1;
}
write(fd,write_buf,sizeof(write_buf));
close(fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc,char **argv[])
{
int ret,fd;
char read_buf[125];
fd = open("./testPipe",O_RDONLY);
if (fd<0)
{
printf("open pipe fail");
return -1;
}
read(fd,read_buf,sizeof(read_buf));
printf("read_buf:%s\n",read_buf);
close(fd);
return 0;
}
多线程
同步与锁机制
信号量灯
信号量灯是信号量的集合,可以对多个信号量同时进行P/V操作
接口
//头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//创建/打开函数
int semget(key_t key,int nsems,int semflag);
/* key: 和信号灯关联的key值
* nsems: 信号灯集包含的信号灯数目
* semflag: 访问权限 IPC_CREAT|0666
* 返回值: 成功返回信号灯id, 失败返回-1
*/
//控制函数
int semctl(int semid,int semnum,int cmd,...union senmun arg);
/* semid: 信号灯集id
* semnum: 要修改的信号灯集编号
* cmd: GETVAL 获取信号量灯的值
* SETVAL 设置信号量灯的值
* IPC_RMID 删除信号量灯
* arg: union semun {
* int val; /* value for SETVAL */
* struct semid_ds *buf; /* Buffer for IPC_STAT,IPC_SET */
* unsigned short *array;/* Array for GETALL,SETALL */
* struct seminfo *__buf;/* Buffer for IPC_INFO(Linux-specific) */
* }
*/
//p/v操作函数
int semop(int semid,struct sembuf *opsptr,size_t nops);
/* semid:信号量灯集id
* opsptr:操作指针
* struct sembuf{
* short sem_num; /* 要操作信号量灯的编号 */
* short sem_op; /* 0:等待信号量灯的值变为0, 1:资源释放(V操作), -1:分配资源(P操作) */
* }
* nops: 要操作信号量灯的个数
*/
Client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
typedef struct
{
int size;
char content[0];
}shm_buf;
#define READ_LOCK 0
#define WRITE_LOCK 1
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void init_sem(int semid,int s[],int n)
{
int i;
union semun myun;
for(i=0;i<n;i++){
myun.val = s[i];
semctl(semid,i,SETVAL,myun);
}
}
void pv(int semid,int num,int op)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = op;
buf.sem_flg = 0;
semop(semid,&buf,1);
}
int main(int argc, char const *argv[])
{
int shmid,semid,s[]={0,1};
int key;
shm_buf *p;
key = ftok("/",1);
if (key<0){
printf("create key fail\n");
return -1;
}
printf("create key success key=0x%X\n",key);
shmid = shmget(key,128,IPC_CREAT|0777);
if(shmid<0){
printf("create shared memory fail\n");
return -1;
}
semid = semget(key,sizeof(s),IPC_CREAT|0666);
if(semid<0){
printf("create sem fail\n");
return -1;
}
printf("create shared memory success ,shmid=%d\n",shmid);
system("ipcs -m");
p = (shm_buf *)shmat(shmid,NULL,0);
if(p == NULL){
printf("shmat fail\n");
return -1;
}
printf("shmat success\n");
while(1)
{
printf("input message: ");
pv(semid,WRITE_LOCK,-1);
fgets(p->content,128,stdin);
p->size = strlen(p->content);
pv(semid,READ_LOCK,1);
}
shmctl(shmid,IPC_RMID,NULL);
semctl(semid,0,IPC_RMID);
return 0;
}
Server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
typedef struct
{
int size;
char content[0];
}shm_buf;
#define READ_LOCK 0
#define WRITE_LOCK 1
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void init_sem(int semid,int s[],int n)
{
int i;
union semun myun;
for(i=0;i<n;i++){
myun.val = s[i];
semctl(semid,i,SETVAL,myun);
}
}
void pv(int semid,int num,int op)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = op;
buf.sem_flg = 0;
semop(semid,&buf,1);
}
int main(int argc, char const *argv[])
{
int shmid,semid,s[]={0,1};
int key;
shm_buf *p;
key = ftok("/",1);
if (key<0){
printf("create key fail\n");
return -1;
}
printf("create key success key=0x%X\n",key);
shmid = shmget(key,128,IPC_CREAT|0777);
if(shmid<0){
printf("create shared memory fail\n");
return -1;
}
semid = semget(key,sizeof(s),IPC_CREAT|0666);
if(semid<0){
printf("create sem fail\n");
return -1;
}
init_sem(semid,s,sizeof(s));
printf("create shared memory success ,shmid=%d\n",shmid);
system("ipcs -m");
p = (shm_buf *)shmat(shmid,NULL,0);
if(p == NULL){
printf("shmat fail\n");
return -1;
}
while(1)
{
pv(semid,READ_LOCK,-1);
if (p->size>0){
printf("shm buf:%s\n", p->content);
p->size = 0;
}
pv(semid,WRITE_LOCK,1);
}
shmctl(shmid,IPC_RMID,NULL);
semctl(semid,0,IPC_RMID);
return 0;
}
内存管理
Socket编程
接口
//Socket函数,用于创建一个socket
int socket(int domain,int type,int protocol);
/* domain: 主机采用的通信协议族, AF_UNIT用于Unit系统的系统进程间通信,AF_INET用于Internet
* type: 通信协议,SOCK_STREAM表示TCP,SOCK_DGRAM表示UDP协议
* protocal:填0
*/
//bind函数
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
/* sockfd: socket文件描述符
* my_addr: socket地址的指针
* addrlen: socket地址长度
*/
//listen函数
int listen(int sockfd,int backlog);
/* sockfd:绑定后的socker描述符
* backlog:请求排队的最大长度
*/
//accept函数
int accept(int sockfd, struct sockaddr *addr,int *addrlen);
/* sockfd:listen后的socker文件描述符
* addr,addren:客户端地址指针和地址长度
*/
//connect函数
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen);
/* sockfd:socket文件描述符
* serv_addr:储存服务器端的连接信息
* addrlen:serv_addr长度
*/
//send函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
/* sockfd: socket文件描述符
* buf:发送数据的缓冲区
* len:发送数据长度
* flags:填0
*/
//recv函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
/* sockfd:socket文件描述符
* buf:接收缓冲区
* len:指明buf的长度
* flag:填0
*/
//recvfrom函数,用于无连接套接字
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
/* sockfd:socket文件描述符
* buf:接收缓冲区
* src_addr: 保存源机的IP和端口
* addlen:sizeof(struct sockaddr)
*/
//sendto函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
/* dest_addr:目的IP和端口
* addrlen: sizeof(struct sockaddr)
* sendto: 时间发送的数据字节长度
*/
TCP
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socker.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h
#define SERVEER_PORT 8081
int main(void)
{
int ret;
int client_socket;
struct sockaddr_in socket_server_addr;
int addr_len;
unsigned char buf[512];
int len;
client_socket = socket(AF_INET,SOCK_STREAM,0);
if (client_socket == -1)
{
printf("socket error");
return -1;
}
socket_server_addr.sin_family = AF_INET;
socket_server_addr.sin_port = htons(SERVER_PORT);
if (inet_aton(argv[1],&socket_server_addr.sin_addr) == 0)
{
printf("invalid server ip");
return -1;
}
memset(socket_server_addr.sin_zero,0,8);
ret = connect(client_socket,(const struct sockaddr *)&socket_server_addr,
sizeof(struct sockaddr));
if(ret == -1)
{
printf("connect error");
return -1;
}
while(1)
{
if (fgets(buf,sizeof(buf),stdin))
{
len = send(client_socket,buf,strlen(buf),0);
if (len <= 0)
{
close(client_socket);
return -1;
}
}
}
close(client_socket);
return 0;
}
服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#define SERVER_PORT 8180
#define C_QUEUE 10
int main(int argc, char **argv)
{
char buf[512];
int len;
int duty_socket;
int customer_socket;
struct sockaddr_in socket_server_addr;
struct sockaddr_in socket_client_addr;
int ret;
int addr_len;
signal(SIGCHLD,SIG_IGN);//父进程死后,让init进程接管子进程,避免子进程成为僵尸进程
duty_socket = socket(AF_INET,SOCK_STREAM,0);
if(duty_socket == -1)
{
printf("socket error");
return -1;
}
socket_server_addr.sin_family = AF_INET;
socket_server_addr.sin_port = htons(SERVER_PORT);
socket_server_addr.sin_addr.s_addr = INADDR_ANY;
memset(socket_server_addr.sin_zero,0,8);
ret = bind(duty_socket,(const struct sockaddr *)&socket_server_addr,
sizeof(struct sockaddr));
if (ret == -1)
{
printf("bind error");
return -1;
}
ret = listen(duty_socket,C_QUEUE);
if (ret == -1)
{
printf("listen error");
return -1;
}
while(1)
{
addr_len = sizeof(struct sockaddr);
customer_socket = accept(duty_socket,(struct sockaddr *)&socket_client_addr,
&addr_len);
if(customer_socket != -1)
{
printf("Get connect from %s\n",inet_ntoa(socket_client_addr.sin_addr));
}
if (!fork())
{
while(1)
{
memset(buf,512,0);
len = recv(customer_socket,buf,sizeof(buf),0);
buf[len] = '\0';
if (len <= 0)
{
close(customer_socket);
return -1;
}
else
{
printf("Get connect from %s, Msg is %s\n",
inet_ntoa(socket_client_addr.sin_addr),buf);
}
}
}
}
close(duty_socket);
return 0;
}
UDP
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 8180
int main(int argc, char **argv)
{
unsigned char buf[512];
int len;
struct sockaddr_in socket_server_addr;
int ret;
int addr_len;
int client_socket;
if (argc != 2)
{
printf("Usage:\n");
printf("%s <server_ip>\n",argv[0]);
return -1;
}
client_socket = socket(AF_INET,SOCK_DRRAM,0);
if (client_socket == -1)
{
printf("socket error");
return -1;
}
socket_server_addr.sin_family = AF_INET;
socket_server_addr.sin_port = htons(SERVER_PORT);
if (inet_aton(argv[1], &socket_server_addr.sin_addr) == 0)
{
printf("invalid server ip\n");
return -1;
}
memset(socket_server_addr.sin_zero,0,8);
while(1)
{
if (fgets(buf,sizeof(buf),stdin))
{
addr_len = sizeof(struct sockaddr);
len = sendto(client_socket,buf,sizeof(buf),0,
(struct sockaddr *)&socket_server_addr,addr_len);
if (len <= 0)
{
close(client_socket);
return -1;
}
}
}
close(client_socket);
return 0;
}
服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#define SERVER_PORT 8180
int main(int argc, char **argv)
{
unsigned char buf[512];
int len;
int duty_socket;
int customer_socket;
struct sockaddr_in socket_server_addr;
struct sockaddr_in socket_client_addr;
int ret;
int addr_len;
duty_socket = socket(AF_INET,SOCK_DGRAM,0);
if (duty_socket == -1)
{
printf("socket error");
return -1;
}
socket_server_addr.sin_family = AF_INET;
socket_server_addr.sin_port = htons(SERVER_PORT);
socket_server_addr.sin_addr.s_addr = INADDR_ANY;
memset(socket_server_addr.sin_zero,0,8);
ret = bind(duty_socket,(const struct sockaddr *)&socket_server_addr,
sizeof(struct sockaddr));
if (ret == -1)
{
printf("bind error");
return -1;
}
while(1)
{
addr_len = sizeof(struct sockaddr);
len = recvfrom(duty_socket,buf,sizeof(buf),0,
(struct sockaddr *)&socket_client_addr,&addr_len);
if (len > 0)
{
buf[len] = '\0';
printf("Get Msg from %s : %s\n",inet_ntoa(socket_client_addr.sin_addr),buf);
}
}
close(duty_socket);
return 0;
}