流式域套接字
服务器端实现
#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;