赞
踩
输入:文件里面的数据输入到内存中
输出:内存中的数据输出到文件中
#include<stdio.h> #include<arpa/inet.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<sys/select.h> int main(){ //创建socket int lfd = socket(PF_INET,SOCK_STREAM,0); if(lfd == -1){ perror("socket"); return -1; } //绑定ip和端口 struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(9999); int ret = bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr)); if(ret == -1){ perror("bind"); return -1; } //监听 ret = listen(lfd,128); if(ret == -1){ perror("listen"); return -1; } //创建一个fd_set的集合,存放的是需要检测的文件描述符 fd_set rdset,tmp; FD_ZERO(&rdset); FD_SET(lfd,&rdset); //最大的文件描述符 int maxfd = lfd; while(1){ tmp = rdset; //调用select系统函数,让内核帮检测哪些文件描述符有数据 ret = select(maxfd+1,&tmp,NULL,NULL,NULL); if(ret == -1){ perror("select"); return -1; }else if(ret == 0){ // 检测的文件描述符里面没有哪个数据到达 //再循环进行检测 continue; }else if(ret > 0){ //说明检测到了有文件描述符的对应的缓冲区的数据发生了改变 //FD_ISSET判断fd对应的标志位0还是1, 返回值:fd对应的标志位的值0或者1 if(FD_ISSET(lfd,&tmp)){ //表示有新的客户端连接进来了 struct sockaddr_in cliaddr; int clilen = sizeof(cliaddr); int cfd = accept(lfd,(struct sockaddr *)&cliaddr,&clilen); //将新的文件描述符加入到集合中 FD_SET(cfd,&rdset); //更新最大的文件描述符 maxfd = maxfd > cfd ? maxfd : cfd; } //看剩余的文件描述符是否发生变化 for(int i = lfd +1;i<= maxfd;++i){ if(FD_ISSET(i,&tmp)){ //说明这个文件描述符对应的客户端发来了数据 char buf[1024] = {0}; int rlen = read(i,&buf,sizeof(buf)); if(rlen == -1){ perror("read"); return -1; }else if(rlen == 0){ printf("client closed....\n"); close(i); //断开连接,将对应的文件描述符对应的标志位设为0 FD_CLR(i,&rdset); }else if(rlen > 0){ printf("read buf : %s\n",buf); //忘记了为啥要加1 write(i,buf,strlen(buf)+1); } } } } } close(lfd); return 0; }
#include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main() { // 创建socket int fd = socket(PF_INET, SOCK_STREAM, 0); if(fd == -1) { perror("socket"); return -1; } struct sockaddr_in seraddr; inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr.s_addr); seraddr.sin_family = AF_INET; seraddr.sin_port = htons(9999); // 连接服务器 int ret = connect(fd, (struct sockaddr *)&seraddr, sizeof(seraddr)); if(ret == -1){ perror("connect"); return -1; } int num = 0; while(1) { char sendBuf[1024] = {0}; sprintf(sendBuf, "send data %d", num++); write(fd, sendBuf, strlen(sendBuf) + 1); // 接收 int len = read(fd, sendBuf, sizeof(sendBuf)); if(len == -1) { perror("read"); return -1; }else if(len > 0) { printf("read buf = %s\n", sendBuf); } else { printf("服务器已经断开连接...\n"); break; } sleep(1); //usleep(1000); } close(fd); return 0; }
#include<stdio.h> #include<arpa/inet.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<poll.h> int main(){ //创建socket int lfd = socket(PF_INET,SOCK_STREAM,0); // if(lfd == -1){ // perror("socket"); // return -1; // } //绑定ip和端口 struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = 0; saddr.sin_port = htons(9999); //int ret = bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr)); bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr)); // if(ret == -1){ // perror("bind"); // return -1; // } //监听 //ret = listen(lfd,8); listen(lfd,8); // if(ret == -1){ // perror("listen"); // return -1; // } //初始化检测的文件描述符 struct pollfd fds[1024]; for(int i =0;i<1024;++i){ fds[i].fd = -1; fds[i].events = POLLIN; } fds[0].fd = lfd; int nfds = 0; while(1){ //调用poll系统函数,让内核帮检测哪些文件描述符有数据 int ret = poll(fds,nfds+1,-1); if(ret == -1){ perror("poll"); return -1; }else if(ret == 0){ //没有检测到有数据的文件描述符 continue; }else if(ret > 0){ //检测到对应文件描述符的对应缓冲区有数据 if(fds[0].revents & POLLIN){ //有新的客户端连接进来了 struct sockaddr_in cliaddr; int clilen = sizeof(cliaddr); int cfd = accept(lfd,(struct sockaddr *)&cliaddr,&clilen); //将新的文件描述符加入到集合中 for(int i = 1; i<1024;i++){ if(fds[i].fd == -1){ fds[i].fd = cfd; fds[i].events = POLLIN; break; } } //加入到集合中之后,更新最大的文件描述符的索引 nfds = nfds > cfd ? nfds:cfd; }//if //查看连接的客户端有没有发来数据 //fds[0] 是监听文件描述符 fds[1]及以后的才是客户端对应的描述符 for(int i =1; i<=nfds; ++i){ if(fds[i].revents & POLLIN){ //说明这个文件描述符对应的客户端发来了数据 //接收,然后再发送回去(回射服务器) char buf[1024]={0}; int rlen = read(fds[i].fd,buf,sizeof(buf)); if(rlen == -1){ perror("read"); return -1; }else if(rlen == 0){ printf("client closed.....\n"); close(fds[i].fd); fds[i].fd = -1; }else if(rlen > 0){ //接收到了数据 printf("resv client data : %s\n",buf); //再把接收到的数据写回去 write(fds[i].fd,buf,strlen(buf)+1); } } } }//else if(ret > 0) }//while(1) close(lfd); return 0; }
#include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main() { // 创建socket int fd = socket(PF_INET, SOCK_STREAM, 0); if(fd == -1) { perror("socket"); return -1; } struct sockaddr_in seraddr; inet_pton(AF_INET, "192.168.49.129", &seraddr.sin_addr.s_addr); seraddr.sin_family = AF_INET; seraddr.sin_port = htons(9999); // 连接服务器 int ret = connect(fd, (struct sockaddr *)&seraddr, sizeof(seraddr)); if(ret == -1){ perror("connect"); return -1; } int num = 0; while(1) { char sendBuf[1024] = {0}; sprintf(sendBuf, "send data %d", num++); write(fd, sendBuf, strlen(sendBuf) + 1); // 接收 int len = read(fd, sendBuf, sizeof(sendBuf)); if(len == -1) { perror("read"); return -1; }else if(len > 0) { printf("read buf = %s\n", sendBuf); } else { printf("服务器已经断开连接...\n"); break; } sleep(1); //usleep(1000); } close(fd); return 0; }
#include<stdio.h> #include<arpa/inet.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<sys/select.h> #include<sys/epoll.h> int main(){ //创建socket int lfd = socket(PF_INET,SOCK_STREAM,0); //绑定ip和端口 struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(9999); bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr)); //监听 listen(lfd,8); //调用epoll_create创建一个epoll实例 int epfd = epoll_create(100); //将监听的文件描述符相关的监测信息添加到epoll实例中 struct epoll_event epev; epev.events = EPOLLIN; epev.data.fd = lfd; epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&epev); //接收检测后的数据 struct epoll_event epevs[1024]; while(1){ int ret = epoll_wait(epfd,epevs,1024,-1); if(ret == -1){ perror("epoll_wait"); return -1; } printf("ret = %d\n",ret); //循环遍历数组epevs,epevs里面有多少个值,通过ret可以知道,ret是发生变化的文件描述符的个数 for(int i =0; i<ret; i++){ if(epevs[i].data.fd == lfd){ //监听的文件描述符有数据到达,有客户端连接 struct sockaddr_in cliaddr; int clilen = sizeof(cliaddr); int cfd = accept(lfd,(struct sockaddr *)&cliaddr,&clilen); //重用之前的epev epev.events = EPOLLIN; epev.data.fd = cfd; //将监听的文件描述符相关的监测信息添加到epoll实例中 epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&epev); }else{ //有数据到达,需要通信 //上一个是监听描述符,如果不是那就是连接的描述符 char buf[1024]={0}; int rlen = read(epevs[i].data.fd,buf,sizeof(buf)); if(rlen == -1){ perror("read"); return -1; }else if(rlen == 0){ printf("client closed.....\n"); epoll_ctl(epfd,EPOLL_CTL_DEL,epevs[i].data.fd,NULL); close(epevs[i].data.fd); //fds[i].fd = -1; }else if(rlen > 0){ //接收到了数据 printf("resv client data : %s\n",buf); //再把接收到的数据写回去 write(epevs[i].data.fd,buf,strlen(buf)+1); } } } } close(lfd); close(epfd); return 0; }
epoll默认触发方式为水平触发
#include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/epoll.h> #include <fcntl.h> #include <errno.h> int main() { // 创建socket int lfd = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in saddr; saddr.sin_port = htons(9999); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; // 绑定 bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)); // 监听 listen(lfd, 8); // 调用epoll_create()创建一个epoll实例 int epfd = epoll_create(100); // 将监听的文件描述符相关的检测信息添加到epoll实例中 struct epoll_event epev; epev.events = EPOLLIN; epev.data.fd = lfd; epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &epev); struct epoll_event epevs[1024]; while(1) { int ret = epoll_wait(epfd, epevs, 1024, -1); if(ret == -1) { perror("epoll_wait"); exit(-1); } printf("ret = %d\n", ret); for(int i = 0; i < ret; i++) { int curfd = epevs[i].data.fd; if(curfd == lfd) { // 监听的文件描述符有数据达到,有客户端连接 struct sockaddr_in cliaddr; int len = sizeof(cliaddr); int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len); // 设置cfd属性非阻塞 int flag = fcntl(cfd, F_GETFL); flag | O_NONBLOCK; fcntl(cfd, F_SETFL, flag); epev.events = EPOLLIN | EPOLLET; // 设置边沿触发 epev.data.fd = cfd; epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &epev); } else { if(epevs[i].events & EPOLLOUT) { continue; } // 循环读取出所有数据 char buf[5]; int len = 0; while( (len = read(curfd, buf, sizeof(buf))) > 0) { // 打印数据 // printf("recv data : %s\n", buf); write(STDOUT_FILENO, buf, len); write(curfd, buf, len); } if(len == 0) { printf("client closed...."); }else if(len == -1) { if(errno == EAGAIN) { printf("data over....."); }else { perror("read"); exit(-1); } } } } } close(lfd); close(epfd); return 0; }
UDP不需要使用多线程多进程就可以实现多个客户端与服务端实现通信
#include<stdio.h> #include<stdlib.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> int main(){ // 1、创建一个通信的socket int lfd = socket(PF_INET,SOCK_DGRAM,0); if(lfd == -1){ perror("socket"); return -1; } // 2、绑定ip和端口 struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(9999); int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr)); if(ret == -1){ perror("bind"); return -1; } //3、通信 while(1){ //接收数据 char recvbuf[128] = {0}; char ipbuf[16] = {0}; struct sockaddr_in cliaddr; int len = sizeof(cliaddr); int num = recvfrom(lfd,recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&cliaddr,&len); //默认已经接收到了数据,就不验证了 printf("client ip : %s, port : %d", inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ipbuf,sizeof(ipbuf)), ntohs(cliaddr.sin_port)); printf("client say : %s\n",recvbuf); //发送数据 +1表示把字符结束符也发送回去 sendto(lfd,recvbuf,sizeof(recvbuf)+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); } close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> int main(){ // 1、创建一个通信的socket int lfd = socket(PF_INET,SOCK_DGRAM,0); if(lfd == -1){ perror("socket"); return -1; } //服务器的地址信息 struct sockaddr_in saddr; saddr.sin_family = AF_INET; //saddr.sin_addr.s_addr = htonl("192.168.49.129"); inet_pton(AF_INET,"192.168.49.129",&saddr.sin_addr.s_addr); saddr.sin_port = htons(9999); int num = 0; //3、通信 while(1){ char sendBuf[128]; sprintf(sendBuf,"hello, i am client %d \n",num++); //发送数据 +1表示把字符结束符也发送回去 sendto(lfd,sendBuf,sizeof(sendBuf)+1,0,(struct sockaddr *)&saddr,sizeof(saddr)); //接收数据 int num = recvfrom(lfd,sendBuf,sizeof(sendBuf),0,NULL,NULL); //默认已经接收到了数据,就不验证了 printf("server say : %s\n",sendBuf); } close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> int main(){ // 1、创建一个通信的socket int lfd = socket(PF_INET,SOCK_DGRAM,0); if(lfd == -1){ perror("socket"); return -1; } //2、设置广播属性 int op = 1; setsockopt(lfd,SOL_SOCKET,SO_BROADCAST,&op,sizeof(op)); // 3、创建一个广播的地址 struct sockaddr_in cliaddr; cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(9999); inet_pton(AF_INET,"192.168.49.255",&cliaddr.sin_addr.s_addr); //3、通信 int num = 0; while(1){ char sendBuf[128]; sprintf(sendBuf,"hello , client .....%d\n",num++); //发送数据 +1表示把字符结束符也发送回去 sendto(lfd,sendBuf,sizeof(sendBuf)+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); printf("广播的数据 : %s\n",sendBuf); sleep(1); } close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> int main(){ // 1、创建一个通信的socket int lfd = socket(PF_INET,SOCK_DGRAM,0); if(lfd == -1){ perror("socket"); return -1; } //2、客户端绑定本地的ip和端口 struct sockaddr_in saddr; saddr.sin_family = AF_INET; //inet_pton(AF_INET,"192.168.49.129",&saddr.sin_addr.s_addr); saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(9999); int ret = bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr)); if(ret == -1){ perror("bind"); return -1; } //3、通信 while(1){ char resvBuf[128]; //接收数据 int num = recvfrom(lfd,resvBuf,sizeof(resvBuf),0,NULL,NULL); //默认已经接收到了数据,就不验证了 printf("server say : %s\n",resvBuf); } close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> int main(){ // 1、创建一个通信的socket int lfd = socket(PF_INET,SOCK_DGRAM,0); if(lfd == -1){ perror("socket"); return -1; } //2、设置多播属性,server端设置多出接口 struct in_addr imr_multiaddr; //初始化多播地址 inet_pton(AF_INET,"239.0.0.10",&imr_multiaddr.s_addr); setsockopt(lfd,IPPROTO_IP,IP_MULTICAST_IF,&imr_multiaddr,sizeof(imr_multiaddr)); // 3、初始化客户端的地址信息 struct sockaddr_in cliaddr; cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(9999); inet_pton(AF_INET,"239.0.0.10",&cliaddr.sin_addr.s_addr); //3、通信 int num = 0; while(1){ char sendBuf[128]; sprintf(sendBuf,"hello , client .....%d\n",num++); //发送数据 +1表示把字符结束符也发送回去 sendto(lfd,sendBuf,sizeof(sendBuf)+1,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); printf("组播的数据 : %s\n",sendBuf); sleep(1); } close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> int main(){ // 1、创建一个通信的socket int lfd = socket(PF_INET,SOCK_DGRAM,0); if(lfd == -1){ perror("socket"); return -1; } //2、客户端绑定本地的ip和端口 struct sockaddr_in saddr; saddr.sin_family = AF_INET; //inet_pton(AF_INET,"192.168.49.129",&saddr.sin_addr.s_addr); saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(9999); int ret = bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr)); if(ret == -1){ perror("bind"); return -1; } struct ip_mreq op; inet_pton(AF_INET,"239.0.0.10",&op.imr_multiaddr.s_addr); op.imr_interface.s_addr = INADDR_ANY; //加入到多播组 setsockopt(lfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&op,sizeof(op)); //3、通信 while(1){ char resvBuf[128]; //接收数据 int num = recvfrom(lfd,resvBuf,sizeof(resvBuf),0,NULL,NULL); //默认已经接收到了数据,就不验证了 printf("server say : %s\n",resvBuf); } close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/un.h> #include<string.h> int main(){ //运行客户端会生成一个server.sock文件,结束, //再重新运行会产生bind:address already in use错误, //将server.sock文件删除就能成功运行(会再生成一个server.sock文件) //而unlink就可以删除这个文件, //每次运行都会检测有没有这个文件,如果有就删除 unlink("server.sock"); //1、创建套接字 int lfd = socket(AF_LOCAL,SOCK_STREAM,0); if(lfd == -1){ perror("socket"); return -1; } //绑定本地套接字文件 struct sockaddr_un addr; addr.sun_family = AF_LOCAL; //sprintf(&addr.sun_path,"server.sock"); strcpy(addr.sun_path,"server.sock"); int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr)); if(ret == -1){ perror("bind"); return -1; } //3、进行监听 ret = listen(lfd,100); if(ret == -1){ perror("listen"); return 0; } //4、接受连接 struct sockaddr_un cliaddr; int clilen = sizeof(cliaddr); int cfd =accept(lfd,(struct sockaddr *)&cliaddr,&clilen); if(cfd == -1){ perror("accept"); return -1; } printf("client socket filename : %s\n",cliaddr.sun_path); //5、通信 while(1){ char buf[1024]; int len = recv(cfd,buf,sizeof(buf),0); if(len == -1){ perror("recv"); return -1; }else if(len == 0){ printf("client closed......"); break; }else if(len > 0){ //接收到了数据 printf("client say : %s \n",buf); send(cfd,buf,len,0); } } close(cfd); close(lfd); return 0; }
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/un.h> #include<string.h> int main(){ //运行客户端会生成一个client.sock文件,结束, //再重新运行会产生bind:address already in use错误, //将client.sock文件删除就能成功运行(会再生成一个client.sock文件) //而unlink就可以删除这个文件 unlink("client.sock"); //1、创建套接字 int cfd = socket(AF_LOCAL,SOCK_STREAM,0); if(cfd == -1){ perror("socket"); return -1; } //绑定本地套接字文件 struct sockaddr_un addr; addr.sun_family = AF_LOCAL; //sprintf(&addr.sun_path,"server.sock"); strcpy(addr.sun_path,"client.sock"); int ret = bind(cfd,(struct sockaddr *)&addr,sizeof(addr)); if(ret == -1){ perror("bind"); return -1; } //3、连接服务端 struct sockaddr_un saddr; saddr.sun_family = AF_LOCAL; strcpy(saddr.sun_path,"server.sock"); ret = connect(cfd,(struct sockaddr *)&saddr,sizeof(saddr)); if(ret == -1){ perror("connect"); return -1; } //4、通信 int num = 0; while(1){ //发送数据 char buf[1024]; sprintf(buf,"hello , i am client %d\n",num++); send(cfd,buf,strlen(buf)+1,0); printf("client say : %s \n",buf); //接收数据 int len = recv(cfd,buf,sizeof(buf),0); if(len == -1){ perror("recv"); return -1; }else if(len == 0){ printf("server closed......"); break; }else if(len > 0){ //接收到了数据 printf("server say : %s \n",buf); } sleep(1); } close(cfd); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。