赞
踩
在客户端输入要上传的照片,服务器就会将图片上传到serpic文件夹中
在服务器输入要发送的照片,服务器就会将图片发送给客户端的mypic文件夹中
有两张图片保存在当前路径下1.png 2.png
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <unistd.h> #include <pthread.h> #include <sys/stat.h> #include <fcntl.h> //图片最大4KB 只能是png,jpg需要改一下代码 #define PSIZE 4*1024 void *send_msg(void *arg); void *recv_msg(void *arg); int main(int argc, char *argv[]) { if(argc != 3){ printf("%s ip port.\n", argv[0]); return -1; } //参数:ip协议 TCP 0 //应用层到底层的通道 int sfd = socket(AF_INET,SOCK_STREAM,0); if(-1 == sfd){ perror("socket"); return -1; } //设置ip port struct sockaddr_in sddr, cddr; memset(&sddr, 0, sizeof(sddr)); bzero(&cddr, sizeof(struct sockaddr_in)); sddr.sin_family = AF_INET; sddr.sin_port = htons(atoi(argv[2])); //设置服务器为自己主机的任意ip == INADDR_ANY sddr.sin_addr.s_addr = inet_addr(argv[1]); int confd = connect(sfd,(void *)&sddr,sizeof(sddr)); if(-1 == confd) { perror("connect"); return -1; } printf("connect success.\n"); //创建两个子线程 pthread_t sid, rid; //发送消息线程 sid = pthread_create(&sid,NULL, send_msg, &sfd); if(sid == -1) { perror("pthread_create1"); return -1; } //接收消息线程 rid = pthread_create(&rid,NULL, recv_msg, &sfd); if(rid == -1) { perror("pthread_create1"); return -1; } while(1){ sleep(1); } return 0; } void *send_msg(void *arg){ int fd = *((int *)arg); char buf[PSIZE] = {0}; char pic_path[20]={0}; while(1){ scanf("%s", pic_path); int pic_fd = open(pic_path,O_RDWR); if(pic_fd < 0) { perror("open"); exit(0); } int n = read(pic_fd,buf,PSIZE); write(fd, buf, n); if(strncmp(buf,"quit",4)==0) exit(0); printf("上传成功!\n"); } } void *recv_msg(void *arg){ int fd = *((int *)arg); char buf[PSIZE] = {0}; int clifd = open("mypic/my_pic.png", O_RDWR|O_CREAT|O_TRUNC, 0666); while(1){ int n = read(fd, buf, PSIZE); if(n==0) exit(0); write(clifd, buf, n); printf("服务器向你发送了一张图片.\n"); } }
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <unistd.h> #include <pthread.h> #include <sys/stat.h> #include <fcntl.h> #define PSIZE 4*1024 void *send_msg(void *arg); void *recv_msg(void *arg); int main(int argc, char *argv[]) { //参数:ip协议 TCP 0 //应用层到底层的通道 int sfd = socket(AF_INET,SOCK_STREAM,0); if(-1 == sfd){ perror("socket"); return -1; } //设置ip port struct sockaddr_in sddr, cddr; memset(&sddr, 0, sizeof(sddr)); bzero(&cddr, sizeof(struct sockaddr_in)); sddr.sin_family = AF_INET; sddr.sin_port = htons(8008); //设置服务器为自己主机的任意ip == INADDR_ANY sddr.sin_addr.s_addr = inet_addr("0.0.0.0"); /* *bind:将ip,port 和 套接字绑定 *参数:sockfd (struct sockaddr *) saddr大小 *返回值 0成功 -1失败 * */ if(-1 == bind(sfd,(void *)&sddr,sizeof(sddr))) { perror("bind"); return -1; } //监听 /* *listen:监听套接字有无连接进来 *sockfd: 目标套接字的文件描述符 *10: 监听队列的长度 *return : 0 success -1 failed * */ if(-1 == listen(sfd, 10)) { perror("listen"); return -1; } puts("listen---------"); /* *accept: 和客户端建立新的连接 *参数:sockfd *cddr: 存储连接进来的客户端信息ip port可以是NULL *len: sizeof(cddr) *return: 表示新的连接 * */ socklen_t len = sizeof(cddr); int nfd = accept(sfd,(void *)&cddr,&len); if(-1 == nfd){ perror("accept"); return -1; } //解析客户端ip 和 port 需要用到inet_ntoa() ntohs()转换 printf("IP:%s PORT:%d connected.\n",inet_ntoa(cddr.sin_addr), ntohs(cddr.sin_port)); //创建两个子线程 pthread_t sid, rid; //发送消息线程 sid = pthread_create(&sid,NULL, send_msg, &nfd); if(sid == -1) { perror("pthread_create1"); return -1; } //接收消息线程 rid = pthread_create(&rid,NULL, recv_msg, &nfd); if(rid == -1) { perror("pthread_create1"); return -1; } while(1){ sleep(1); } return 0; } void *send_msg(void *arg){ //可以向客户端发送一张图片 int fd =*(int *)arg; char buf[PSIZE] = {0}; char pic_path[20] = {0}; while(1){ scanf("%s", pic_path); int picfd = open(pic_path,O_RDWR); if(picfd < 0) { perror("picfd"); exit(0); } int n = read(picfd, buf, PSIZE); if(strncmp(buf,"quit",4)==0) exit(0); write(fd, buf, n); } } void *recv_msg(void *arg){ //接收客户端发过来的图片 保存为serpic.png int fd = *((int *)arg); char buf[PSIZE] = {0}; int picfd = open("serpic/serpic.png",O_RDWR|O_CREAT|O_TRUNC, 0666); while(1){ sleep(1); int n = read(fd, buf, PSIZE); if(n==0) exit(0); write(picfd, buf, n); printf("已将图片保存为serpic.png.\n"); } }
gcc pic_client.c -o pic_cli -lpthread
gcc pic_server.c -o pic_ser -lpthread
打开两个终端
第一个终端输入:
./pic_ser
第二个终端输入:
./pic_cli 127.0.0.1 8008
如果出现bind:地址已被占用 关闭所有终端重新再来,实在不行就挂起虚拟机再开
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。