/* ************************************************** */
/* Image Receiver Program (ARM version) */
/* This Program is to receive the jpeg image file */
/* and show the jpeg image file */
/* */
/* 2006.7.7 Made By Jung Yong Hak */
/* ************************************************** */
/* Image Receiver Program (ARM version) */
/* This Program is to receive the jpeg image file */
/* and show the jpeg image file */
/* */
/* 2006.7.7 Made By Jung Yong Hak */
/* ************************************************** */
// header file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#define BUFSIZE 4096
void error_handling(char *message);
// 사용자 정의 데이터 수신 함수
int recvn(int s, char *buf, int len, int flags)
{
int received; //리턴 상태 표시 변수
char *ptr = buf; //받은 데이터를 저장할 버퍼에 대한 포인터
int left = len; //남은 크기(바이트 수) 저장할 변수
int recvn(int s, char *buf, int len, int flags)
{
int received; //리턴 상태 표시 변수
char *ptr = buf; //받은 데이터를 저장할 버퍼에 대한 포인터
int left = len; //남은 크기(바이트 수) 저장할 변수
while(left > 0){
// 네트워크로 받은 바이트의 수를 리턴
received = recv(s, ptr, left, flags);
// 받기 실패시 -1 리턴
if(received == -1)
return -1;
else if(received == 0)
break;
left -= received; // 받은 바이트 수 만큼 빼서 남은 크기를 알려줌
ptr += received; // 포인터은 받은 바이트 수 만큼 더해준다
}
// 네트워크로 받은 바이트의 수를 리턴
received = recv(s, ptr, left, flags);
// 받기 실패시 -1 리턴
if(received == -1)
return -1;
else if(received == 0)
break;
left -= received; // 받은 바이트 수 만큼 빼서 남은 크기를 알려줌
ptr += received; // 포인터은 받은 바이트 수 만큼 더해준다
}
return (len - left); // 전체 길이에서 남은 바이트 수를 빼서 리턴
}
}
int main(int argc, char* argv[])
{
//argument
int serv_sock,client_sock;
int retval,i,addrlen,numtotal=0;
int kill_pid, check_pid=1, totalbytes=0;
char buf[BUFSIZE];
char system_arg[256];
char filename[256],file_tmp[256]="2006";
struct sockaddr_in serveraddr,clientaddr;
FILE *fp;
pid_t pid;
char *exec_arg[4];
{
//argument
int serv_sock,client_sock;
int retval,i,addrlen,numtotal=0;
int kill_pid, check_pid=1, totalbytes=0;
char buf[BUFSIZE];
char system_arg[256];
char filename[256],file_tmp[256]="2006";
struct sockaddr_in serveraddr,clientaddr;
FILE *fp;
pid_t pid;
char *exec_arg[4];
puts("Image Receiver Program");
puts("=========================================");
puts("=========================================");
// socket()
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
if(serv_sock == -1) error_handling("socket()");
// bind()
memset(&serveraddr,0,sizeof(serveraddr));
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
if(serv_sock == -1) error_handling("socket()");
// bind()
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(9000);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(serv_sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
if(retval == -1) error_handling("bind()");
// listen()
retval = listen(serv_sock, 5);
if(retval == -1) error_handling("listen()");
if(retval == -1) error_handling("bind()");
// listen()
retval = listen(serv_sock, 5);
if(retval == -1) error_handling("listen()");
while(1)
{
// accept()
addrlen = sizeof(clientaddr);
client_sock = accept(serv_sock, (struct sockaddr *)&clientaddr, &addrlen);
if(client_sock == -1)
{
error_handling("accept()");
continue;
}
{
// accept()
addrlen = sizeof(clientaddr);
client_sock = accept(serv_sock, (struct sockaddr *)&clientaddr, &addrlen);
if(client_sock == -1)
{
error_handling("accept()");
continue;
}
// 접속 ip 와 port를 출력
printf("IP =%s, port =%dn",
inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
memset(&filename,0, 256);
printf("IP =%s, port =%dn",
inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
memset(&filename,0, 256);
// 받은 원래 파일 이름 출력 (후에 파일이름 변경한다)
retval = recvn(client_sock, filename, 256, 0);
if(retval == -1)
{
error_handling("recv()");
close(client_sock);
continue;
}
printf("-> original file name : %sn", filename);
retval = recvn(client_sock, (char *)&totalbytes, sizeof(totalbytes), 0);
retval = recvn(client_sock, filename, 256, 0);
if(retval == -1)
{
error_handling("recv()");
close(client_sock);
continue;
}
printf("-> original file name : %sn", filename);
retval = recvn(client_sock, (char *)&totalbytes, sizeof(totalbytes), 0);
// 파일 크기 출력
if(retval == -1 )
{
error_handling("recv()");
close(client_sock);
continue;
}
printf("-> file size : %dn", totalbytes);
if(retval == -1 )
{
error_handling("recv()");
close(client_sock);
continue;
}
printf("-> file size : %dn", totalbytes);
// 파일 이름 변경 후 출력
for(i=26;i<45;i++)
{
file_tmp[i-22]=filename[i];
}
strcpy(filename,file_tmp);
printf("-> changed file name : %sn",filename);
for(i=26;i<45;i++)
{
file_tmp[i-22]=filename[i];
}
strcpy(filename,file_tmp);
printf("-> changed file name : %sn",filename);
// 파일 열기
fp= fopen(filename, "wb");
if(fp == NULL)
{
perror("파일 입출력 오류");
close(client_sock);
continue;
}
fp= fopen(filename, "wb");
if(fp == NULL)
{
perror("파일 입출력 오류");
close(client_sock);
continue;
}
while(1)
{
retval = recvn(client_sock, buf, BUFSIZE, 0);
//retval이 -1이면 에러
if(retval == -1)
{
error_handling("recv()");
break;
}
//retval이 0이면 전체파일 다 보냈다는 것
else if(retval == 0)
break;
else
{
/* 1바이트 크기의 데이터를 retval개수 만큼 fp로 출력
buf는 출력하고자 하는 데이터의 시작위치를 가리키는 포인터 */
fwrite(buf, 1, retval, fp);
if(ferror(fp))
{
perror("파일 입출력 오류");
break;
}
numtotal += retval; //받은 만큼 + 시켜준다
}
}
fclose(fp);
{
retval = recvn(client_sock, buf, BUFSIZE, 0);
//retval이 -1이면 에러
if(retval == -1)
{
error_handling("recv()");
break;
}
//retval이 0이면 전체파일 다 보냈다는 것
else if(retval == 0)
break;
else
{
/* 1바이트 크기의 데이터를 retval개수 만큼 fp로 출력
buf는 출력하고자 하는 데이터의 시작위치를 가리키는 포인터 */
fwrite(buf, 1, retval, fp);
if(ferror(fp))
{
perror("파일 입출력 오류");
break;
}
numtotal += retval; //받은 만큼 + 시켜준다
}
}
fclose(fp);
// 전송 결과 출력
if(numtotal == totalbytes)
{
printf("-> file transfer success!n");
numtotal=0;
}
else
{
printf("-> file transfer fail!n");
numtotal=0;
}
if(numtotal == totalbytes)
{
printf("-> file transfer success!n");
numtotal=0;
}
else
{
printf("-> file transfer fail!n");
numtotal=0;
}
// 파일 전송후 close client_socket
close(client_sock);
close(client_sock);
// argument 입력
exec_arg[0]="showimg";
exec_arg[1]="-qws";
exec_arg[2]=filename;
exec_arg[3]=0; // 0 == NULL
exec_arg[0]="showimg";
exec_arg[1]="-qws";
exec_arg[2]=filename;
exec_arg[3]=0; // 0 == NULL
// check_pid 가 0일 경우
if(check_pid==0)
{
// system_arg변수에 kill PID를 입력후 실행 해서 프로세스를 죽임
sprintf(system_arg, "kill %d",kill_pid);
system(system_arg);
// 프로세스 체크 변수에 1 대입
check_pid=1;
}
if(check_pid==0)
{
// system_arg변수에 kill PID를 입력후 실행 해서 프로세스를 죽임
sprintf(system_arg, "kill %d",kill_pid);
system(system_arg);
// 프로세스 체크 변수에 1 대입
check_pid=1;
}
switch(pid=fork())
{
case -1:
printf("errorn");
break;
case 0:
// print the current PID and parent PID & save current PID
printf("parent PID : %d, current PID : %dn", getppid(), getpid());
kill_pid=getpid();
// execv
execv("/jffs/Qtopia/bin/showimg",exec_arg);
// 프로세스가 살아 있다는 걸 알리기 위한 변수에 0 입력
check_pid=0;
break;
default:
break;
}
{
case -1:
printf("errorn");
break;
case 0:
// print the current PID and parent PID & save current PID
printf("parent PID : %d, current PID : %dn", getppid(), getpid());
kill_pid=getpid();
// execv
execv("/jffs/Qtopia/bin/showimg",exec_arg);
// 프로세스가 살아 있다는 걸 알리기 위한 변수에 0 입력
check_pid=0;
break;
default:
break;
}
}
// closesocket()
close(serv_sock);
close(serv_sock);
return 0;
}
}
// 소켓 함수 오류 출력 후 종료
void error_handling(char *message)
{
fputs(message, stderr);
fputc('n',stderr);
exit(1);
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('n',stderr);
exit(1);
}