流式域套接字
服务器端实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, const char *argv[])
{int fp=socket(AF_UNIX,SOCK_STREAM,0);if(fp==-1){perror("socket");return -1;}if(access("./pith",F_OK)==0){ if(unlink("./pith")==-1){perror("unlink");return -1;}}struct sockaddr_un cin;cin.sun_family=AF_UNIX;strcpy(cin.sun_path,"./pith");if(bind(fp,(struct sockaddr*)&cin,sizeof(cin))==-1){perror("bind");return -1;}listen(fp,128);struct sockaddr_un sin;socklen_t sinlen=sizeof(sin);int rfp=accept(fp,(struct sockaddr*)&sin,&sinlen);if(rfp==-1){perror("accept");return -1;}char buf[128];while(1){bzero(buf,sizeof(buf));recv(rfp,buf,sizeof(buf),0);printf("%s\n",buf);}close(fp);return 0;
}
报式域套接字
服务器端实现
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <pthread.h>#include <semaphore.h>#include <wait.h>#include <signal.h>#include <sys/socket.h>#include <arpa/inet.h>#include <sys/socket.h>#include <sys/ipc.h>#include <sys/sem.h>#include <semaphore.h>#include <sys/msg.h>#include <sys/shm.h>#include <sys/un.h>#include <sys/socket.h>#include <netinet/in.h>int main(int argc, const char *argv[]){int fp=socket(AF_UNIX,SOCK_DGRAM,0);if(fp==-1){perror("socket");return -1;}if(access("./pith",F_OK)==0){if(unlink("./pith")==-1){perror("unlink");return -1;}}struct sockaddr_un cin;cin.sun_family=AF_UNIX; strcpy(cin.sun_path,"./pith");if(bind(fp,(struct sockaddr*)&cin,sizeof(cin))==-1){perror("bind");return -1;}struct sockaddr_un sin;socklen_t sinlen=sizeof(sin);char buf[128];while(1){bzero(buf,sizeof(buf));recv(fp,buf,sizeof(buf),0);send(fp, buf, strlen(buf),0);printf("%s\n",buf);}close(fp);return 0;}
组播接收端的实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, const char *argv[])
{int fp=socket(AF_INET,SOCK_DGRAM,0);if(fp==-1){perror("socket");return -1;}struct ip_mreqn sin;sin.imr_multiaddr.s_addr=inet_addr("224.1.2.3");sin.imr_address.s_addr=inet_addr("192.168.125.113");sin.imr_ifindex=2;if(setsockopt(fp,IPPROTO_IP,IP_ADD_MEMBERSHIP,&sin,sizeof(sin))==-1){ perror("setsockopt");return -1;}struct sockaddr_in cin;cin.sin_family=AF_INET;cin.sin_port=htons(5555);cin.sin_addr.s_addr=inet_addr("224.1.2.3");if(bind(fp,(struct sockaddr*)&cin,sizeof(cin))==-1){perror("bind");return -1;}char buf[128];while(1){bzero(buf,sizeof(buf));recv(fp,buf,sizeof(buf),0);printf("%s\n",buf);if(strcmp(buf,"over")==0){break;}}close(fp);return 0;
}
广播接收端的实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <sys/socket.h>
int main(int argc, const char *argv[])
{int fp=socket(AF_INET,SOCK_DGRAM,0);if(fp==-1){perror("socket");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(6666);sin.sin_addr.s_addr=inet_addr("192.168.125.255");int size=sizeof(sin);if(bind(fp,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind");return -1;}char buf[128];while(1){bzero(buf,sizeof(buf));recvfrom(fp,buf,sizeof(buf),0,(struct sockaddr*)&sin,&size);printf("%s\n",buf);if(strcmp(buf,"over")==0){break;}}return 0;
}
一、项目中如何实现TCP的并发
多进程实现:
- 创建服务器端套接字
- 将套接字绑定端口号和IP地址
- 设置该套接字被动监听状态
- 循环接受客户端的连接请求
- 创建子进程
- 在子进程中与接受的客户端进行数据收发
- 关闭连接
多线程实现:
- 创建服务器端套接字
- 将套接字绑定端口号和IP地址。
- 设置该套接字被动监听状态
- 循环接受客户端的连接请求
- 创建新线程
- 在分线程中与接受的客户端进行数据收发
- 关闭连接
二、TCP通信过程中的三次手
-
第一次握手: 客户端向服务端发送一个连接请求
-
第二次握手: 服务器收到客户端连接请求后,给客户端发送一个自己收到的消息,并且再发送连接请求
-
第三次握手: 客户端收到服务端连接请求后,给服务端发送一个自己收到的消息
三、四次挥手的过程
-
第一次挥手: 客户端向服务端发送一个断开请求
-
第二次挥手:服务器收到客户端断开请求后,给客户端发送一个自己收到的消息
-
第三次挥手: 服务端向客户端发送一个断开请求
-
最后一次挥手: 客户端收到服务端连接请求后,给服务端发送一个自己收到的消息
四、UDP为什么丢包,怎么处理?丢包发生在哪一层,为什么?
因为UDP面向无连接的,并不像TCP面向有连接的那样稳定
减小发生数据的速率
网络层
因为数据包丢失这些问题发送在网络层
五、TCP是同步还是异步,谈谈对同步异步的理解
同步
同步:指程序按顺序执行,每一个操作需要等待上一个操作执行完才开始执行
异步:指程序不按顺序执行,每一个操作不需要等待上一个操作执行完才开始执行
六、为什么TCP会发粘包,怎么处理
当发送的数据包很小时,会将这个数据包和下个数据包一起发送
减小发送数据包的速率
七、组播和广播的区别
范围:广播发送数据给同一网络下的每个主机,组播发送到一个多播组里,只有加入这个组里的主机才能收到数据
IP地址:广播地址为网络号+255,组播地址为D类网络
八、阻塞IO和非阻塞IO的区别
在阻塞IO中,当应用程序发起一个IO操作时,程序会一直等待,直到操作完成并返回结果。
在阻塞IO中,如果没有数据可读取或无法立即进行写入,程序将被阻塞,无法执行其他任务,直到IO操作完成
在非阻塞IO中,当应用程序发起一个IO操作时,程序会立即返回,不会等待操作完成。
在非阻塞IO中,如果没有数据可读取或无法立即进行写入,程序也会立即返回,而不会被阻
九、并发和并行的区别
并发:表面是多个任务同时执行,实际是多个任务交替执行,只有获得时间片的任务才开始执行,一个时间段类只有一个任务在执行,但因为处理速度很快,这个时间段一般很小
并行:真正意义是的多个任务同时执行,利用多核处理器同时执行各个任务
include <stdio.h>
include <unistd.h>
include <stdlib.h>
include <sys/types.h>
include <sys/stat.h>
include <fcntl.h>
include <pthread.h>
include <semaphore.h>
include <wait.h>
include <signal.h>
include <sys/socket.h>
include <arpa/inet.h>
include <sys/socket.h>
include <sys/ipc.h>
include <sys/sem.h>
include <semaphore.h>
include <sys/msg.h>
include <sys/shm.h>
include <sys/un.h>
include <sys/socket.h>
nt main(int argc, const char *argv[])int fp=socket(AF_INET,SOCK_STREAM,0);if(fp==-1){perror("soket");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(69);sin.sin_addr.s_addr=inet_addr(argv[1]);socklen_t len=sizeof(sin);while(1){printf("**********************\n");printf("********1.下载********\n");printf("********2.上传********\n");printf("********3.退出********\n");printf("**********************\n");short x;char buf[516]="";scanf("%d\n",&x);while(getchar()!=10);short *p1=buf;*p1=htons(x);printf("请输入要下载的文件名>>>");char *p2=buf+2;char name[128]="";scanf("%s",name);while(getchar()!=10);strcpy(p2,name);char *p4=p2+strlen(p2)+1;strcpy(p4,"SOCK_STREAM");int size=2+strlen(p2)+strlen(p4)+2;if(sendto(fp,buf,size,0,(struct sockadd*)&sin,sizeof(sin))==-1){perror("send");return -1;}while(1){ if(x==1){bzero(buf,sizeof(buf));if(recvfrom(fp,buf,sizeof(buf),0,(struct sockaddr*)&sin,&sizeof(sin))==-1);{perror("recvfrom");return -1;}short* p1=buf;short* p2=buf+1;if(*p1==3){int p=1;if(*p2==p){printf("下载中\n");p++;}else{}}else if(*p1==5){if(*p2==0){}else if(*p2==1){}else if(*p2==2){}else if(*p2==3){}else if(*p2==4){}else if(*p2==5){}}}}else if(x==2){bzero(buf,sizeof(buf));send(fp,buf,sizeof(buf),0);short* p1=buf;short* p2=buf+1;if(buf==3){printf("上传中\m");}}}close(fp);return 0;