/*TCP并发服务器端*/
#include <myhead.h>
#define SER_IP "192.168.125.173"
#define SER_PORT 8888
void sighanger(int signum){
if(signum==SIGCHLD){//子进程终止信号
while(waitpid(-1,NULL,WNOHANG)>0);//循环回收僵尸进程
}
}
int main(int argc, const char *argv[])
{
//函数调用出错返回SIG_ERR
if(signal(SIGCHLD,sighanger)==SIG_ERR){
perror("signal error");
return -1;
}
//创建套接字
int rfd=socket(AF_INET,SOCK_STREAM,0);
if(rfd==-1){
perror("socket error");
return -1;
}
printf("socket success\n");
//为服务器绑定ip地址端口号
struct sockaddr_in cin;
cin.sin_family=AF_INET;
cin.sin_port=htons(SER_PORT);
cin.sin_addr.s_addr=inet_addr(SER_IP);
if(bind(rfd,(struct sockaddr*)&cin,sizeof(cin))==-1){
perror("bind error");
return -1;
}
//设置监听
if(listen(rfd,128)==-1){
perror("listen error");
return -1;
}
printf("listen success\n");
struct sockaddr_in sin;
socklen_t socklen=sizeof(sin);
while(1){//循环接收客户端请求
int newfd=accept(rfd,(struct sockaddr*)&sin,&socklen);
if(newfd==-1){
perror("accept error");
return -1;
}
pid_t pid=fork();
if(pid>0){
close(newfd);
}else if(pid==0){//子进程数据通信
close(rfd);
char rbuf[128]="";
while(1){
bzero(rbuf,sizeof(rbuf));
int res=read(newfd,rbuf,sizeof(rbuf));
if(res==0){
printf("客户端已下线\n");
break;
}
printf("[%s:%d]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf);
//将字符串加777发送回去
strcat(rbuf,"777");
write(newfd,rbuf,sizeof(rbuf));
printf("发送成功\n");
}
close(newfd);
exit(EXIT_SUCCESS);
}
}
close(rfd);
return 0;
}
//多线程实现TCP并发服务器
#include<myhead.h>
#define SER_IP "192.168.125.117" //服务器IP地址
#define SER_PORT 8888 //服务器端口号
//定义用于给线程体传参的结构体类型
struct MsgInfo
{
int newfd;
struct sockaddr_in cin;
};
//定义线程体函数
void *deal_cli_msg(void *arg)
{
//将传递进来的数据解析出来
int newfd = ((struct MsgInfo*)arg)->newfd;
struct sockaddr_in cin = ((struct MsgInfo*)arg)->cin;
//5、数据通信
char rbuf[128] = ""; //用于接受消息
while(1)
{
bzero(rbuf, sizeof(rbuf)); //清空容器
//从套接字文件中读取消息
//int ret = read(newfd, rbuf, sizeof(rbuf));
int ret = recv(newfd, rbuf, sizeof(rbuf), 0);
if(ret == 0)
{
printf("客户端已下线\n");
break;
}
printf("[%s:%d]: %s\n", \
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),rbuf );
//将字符串加个笑脸回回去
strcat(rbuf, "*_*");
//write(newfd, rbuf, strlen(rbuf));
send(newfd, rbuf, strlen(rbuf), 0);
printf("发送成功\n");
}
//6、关闭套接字
close(newfd);
//退出线程
pthread_exit(NULL);
}
/**主程序**/
int main(int argc, const char *argv[])
{
//1、创建套节字:用于接收客户端链接请求的
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success sfd = %d\n", sfd); //3
//设置端口号快速重用
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1)
{
perror("setsockopt error");
return -1;
}
printf("端口号快速重用成功\n");
//2、绑定IP地址和端口号
//2.1 填充地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET; //地址族
sin.sin_port = htons(SER_PORT); //端口号
sin.sin_addr.s_addr = inet_addr(SER_IP); //IP地址
//2.2 绑定工作
if( bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) ==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、讲套节字设置成被动监听状态
if( listen(sfd, 128) == -1)
{
perror("listen error");
return -1;
}
printf("listen success\n");
//4、阻塞等待客户端连接请求
//定义地址信息结构体变量用于接受客户端的地址信息
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin); //接受地址信息的长度
while(1)
{
int newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
if(newfd == -1)
{
perror("accept error");
return -1;
}
printf("[%s:%d]:已连接, newfd = %d\n",\
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port) ,newfd); //4
//定义用于传参的变量
struct MsgInfo info = {newfd, cin};
//创建分支线程用于通信
pthread_t tid = -1;
if(pthread_create(&tid, NULL, deal_cli_msg, &info) != 0)
{
printf("线程创建失败\n");
return -1;
}
//回收分支线程的资源
pthread_detach(tid);
}
close(sfd);
return 0;
}
//流式域套接字服务器端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建套节字:用于接收客户端链接请求的
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success sfd = %d\n", sfd); //3
//判断要绑定的套接字文件是否存在,如果存在,需要将其删除
if(access("./unix", F_OK) == 0)
{
//说明文件存在,需要将其删除
if(unlink("./unix") != 0)
{
perror("unlink error");
return -1;
}
}
//2、绑定套接字文件
//2.1 填充地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX; //通信域
strcpy(sun.sun_path , "./unix"); //套接字文件
//2.2 绑定工作
if( bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) ==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、讲套节字设置成被动监听状态
if( listen(sfd, 128) == -1)
{
perror("listen error");
return -1;
}
printf("listen success\n");
//4、阻塞等待客户端连接请求
//定义地址信息结构体变量用于接受客户端的地址信息
struct sockaddr_un cun;
socklen_t socklen = sizeof(cun); //接受地址信息的长度
int newfd = accept(sfd, (struct sockaddr*)&cun, &socklen);
if(newfd == -1)
{
perror("accept error");
return -1;
}
printf("[%s]:已连接, newfd = %d\n", cun.sun_path,newfd); //4
//5、数据通信
char rbuf[128] = ""; //用于接受消息
while(1)
{
bzero(rbuf, sizeof(rbuf)); //清空容器
//从套接字文件中读取消息
//int ret = read(newfd, rbuf, sizeof(rbuf));
int ret = recv(newfd, rbuf, sizeof(rbuf), 0);
if(ret == 0)
{
printf("客户端已下线\n");
break;
}
printf("[%s]: %s\n", cun.sun_path ,rbuf );
//将字符串加个笑脸回回去
strcat(rbuf, "*_*");
//write(newfd, rbuf, strlen(rbuf));
send(newfd, rbuf, strlen(rbuf), 0);
printf("发送成功\n");
}
//6、关闭套接字
close(newfd);
close(sfd);
return 0;
}
//报式域套接字服务器端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建用于通信的套接字文件描述符
int sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success sfd = %d\n", sfd); //3
//判断要绑定的套接字文件是否存在,如果存在,需要将其删除
if(access("./unix", F_OK) == 0)
{
//说明文件存在,需要将其删除
if(unlink("./unix") != 0)
{
perror("unlink error");
return -1;
}
}
//2、绑定IP地址和端口号
//2.1 填充地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX; //协议族
strcpy(sun.sun_path, "./unix"); //服务器的套接字文件
//2.2 绑定工作
if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、数据的收发
//定义变量接收客户端地址信息结构体
struct sockaddr_un cun;
socklen_t socklen = sizeof(cun);
char rbuf[128] = "";
while(1)
{
bzero(rbuf, sizeof(rbuf));
//读取套接字中的数据
recvfrom(sfd, rbuf, sizeof(rbuf), 0, (struct sockaddr*)&cun, &socklen);
printf("[%s]:%s\n",cun.sun_path, rbuf);
//加个笑脸将消息回回去
strcat(rbuf, "*_*");
if(sendto(sfd, rbuf, strlen(rbuf), 0, (struct sockaddr*)&cun, sizeof(cun)) ==-1)
{
perror("write error");
return -1;
}
printf("发送成功\n");
}
//4、关闭套接字
close(sfd);
return 0;
}
通过TFTP用UDP实现上传和下载文件
cs
复制代码
#include <myhead.h>
#define SER_IP "192.168.125.99"
#define SER_PORT 69
#define IP "192.168.125.173"
#define PORT 8888
void download(char data[],short* p1,char* p2){
char filename[128]="";
printf("请输入要下载的文件名:");
fgets(filename,sizeof(filename),stdin);
filename[strlen(filename)-1]=0;
int fp=open(filename,O_WRONLY | O_CREAT|O_TRUNC, 0664);//创建文件
if(fp==-1){
perror("open error");
return ;
}
*p1=htons(1);//下载
strcpy(p2,filename);
char* p4=p2+strlen(filename)+1;
strcpy(p4,"octet");
int len=4+strlen(filename)+strlen("octet");
printf("%s\n",p2);
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1){
perror("socket error");
return ;
}
struct sockaddr_in rin;
rin.sin_family=AF_INET;
rin.sin_port=htons(PORT);
rin.sin_addr.s_addr=inet_addr(IP);
if(bind(sfd,(struct sockaddr*)&rin,sizeof(rin))==-1){
perror("bind error");
return ;
}
printf("bind success\n");
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
socklen_t sin_size = sizeof(sin);
//发送下载请求
sendto(sfd,data,len,0,(struct sockaddr*)&sin,sizeof(sin));
char buf[516];
short ack[2];
ack[0]=htons(4);
int res;
while(1){
bzero(buf,sizeof(buf));
//接收数据到buf
res=recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &sin_size);
//返回接收数据字节数
//从返回数据包中取出块编号,放到ack中去
ack[1]=*(short*)(buf+2);
//返回ACK确认
sendto(sfd, ack, sizeof(ack), 0, (struct sockaddr*)&sin, sin_size);
//将buf中的数据写到文件
write(fp,buf+4,res-4);//写res-4个数据从buf+4位置到文件
if(res!=516){
break;
}
}
close(fp);
}
void transmit(char data[],short* p1,char* p2){
char filename[128]="";
printf("请输入要上传的文件名:");
fgets(filename,sizeof(filename),stdin);
filename[strlen(filename)-1]=0;
*p1=htons(2);//写,上传请求
int fp=open(filename,O_RDONLY, 0664);//打开文件
strcpy(p2,filename);
char* p4=p2+strlen(filename)+1;
strcpy(p4,"octet");
int len=4+strlen(filename)+strlen("octet");
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1){
perror("socket error");
return ;
}
struct sockaddr_in rin;
rin.sin_family=AF_INET;
rin.sin_port=htons(PORT);
rin.sin_addr.s_addr=inet_addr(IP);
if(bind(sfd,(struct sockaddr*)&rin,sizeof(rin))==-1){
perror("bind error");
return ;
}
printf("bind success\n");
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
socklen_t sin_size = sizeof(sin);
//发送下载请求
sendto(sfd,data,len,0,(struct sockaddr*)&sin,sizeof(sin));
int count=1;
*p1=htons(3);
short* p10=data+2;
while(1){
*p10=htons(count);
int ress=read(fp,data+4,512);
if(ress==0){break;}
sendto(sfd, data, sizeof(data), 0, (struct sockaddr*)&sin, sin_size);
count++;
}
close(fp);
}
int main(int argc, const char *argv[])
{
printf("1.下载2.上传");
printf("请输入>>>");
int flag=0;
scanf("%d",&flag);
while(getchar()!=10);
char data[516]="";
short* p1=data;
char* p2=data+2;
if(flag==1){
download(data,p1,p2);
}else if(flag==2){
transmit(data,p1,p2);
}
return 0;
}