소켓 select 뭐가 문제일까요?
글쓴이: gag2012 / 작성시간: 수, 2018/06/06 - 1:00오후
서버코드입니다.
#include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #define SERV_TCP_PORT #define SERV_ADDR "" void transfile(int s2); void receivefile(int s2); void main(){ int s1,s2, x, y; struct sockaddr_in serv_addr, cli_addr; char buf[50]; socklen_t xx; printf("Hi, I am the server\n"); bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family=PF_INET; serv_addr.sin_addr.s_addr=inet_addr(SERV_ADDR); serv_addr.sin_port=htons(SERV_TCP_PORT); //open a tcp socket if ((s1=socket(PF_INET, SOCK_STREAM, 0))<0){ printf("socket creation error\n"); exit(1); } // bind ip x =bind(s1, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); if (x < 0){ printf("binding failed\n"); exit(1); } printf("binding passed\n"); listen(s1, 5); xx = sizeof(cli_addr); int i,k,f; char doit[50]; char str[50]; for(i; i<3; i++){ s2 = accept(s1, (struct sockaddr *)&cli_addr, &xx); printf("we passed accept. new socket num is %d\n", s2); k = fork(); if(k==0){ printf("now connect with client %d \n", s2); printf("========================\n"); y = read(s2, buf, 50); buf[y]=0; if(strcmp(buf, "hello")==0) { printf("successfull connect!\n"); write(s2, "Type <download> or <upload>", 27); y= read(s2, doit, 50); doit[y] = 0; if(strcmp(doit, "download")==0) transfile(s2); else if(strcmp(doit, "upload")==0) receivefile(s2); } close(s2); close(s1); exit(0); } //child do else { close(s2); } //parent do } close(s1); // close the original socket }
receivefile()함수입니다.
void receivefile(int s2){ struct timeval timeout; int x, y, cnt, rv; char fileName[50]; char content[60]; fd_set rset, temp; FD_ZERO(&rset); FD_ZERO(&temp); FD_SET(s2, &rset); timeout.tv_sec = 3; timeout.tv_usec = 0; printf("receivefile_mode\n"); write(s2, "which file you want?", 20); y = read(s2, fileName, 50); fileName[y] = 0; printf("client : %s\n", fileName); x = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 00777); if (x<0){ write(s2, "protocol error", 20); close(y); return; } for(cnt; cnt<20; cnt++){ printf("!!!!이 부분이 출력되지 않습니다!!!!\n"); FD_SET(s2, &rset); temp = rset; /* upload */ rv = select(s2+1, &temp, NULL, NULL, &timeout); if(rv==-1){ perror("select"); } else if(rv==0){ break; } else { if(FD_ISSET(s2, &temp)){ y = read(s2, content, 50); content[y] = 0; write(1, content, y); write(x, content, y); } } } printf("\n socket : %s done\n", s2); }
클라이언트는 윈도우 비주얼스튜디오에서 진행했습니다.
#include "winsock2.h" #include "ws2tcpip.h" #include "stdio.h" #pragma warning (disable : 4996) #define SERVER_PORT 24680 // server port number #define BUF_SIZE 4096 // block transfer size #define QUEUE_SIZE 10 #define IPAddress "165.246.38.151" // server IP address void download(int s, int n, char buf[]); void upload(int s, int n, char buf[]); int main() { WORD wVersionRequested; WSADATA wsaData; SOCKADDR_IN target; //Socket address information SOCKET s; int err; int bytesSent; char buf[100]; //--- INITIALIZATION ----------------------------------- wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("WSAStartup error %ld", WSAGetLastError()); WSACleanup(); return false; } //------------------------------------------------------ //---- Build address structure to bind to socket.-------- target.sin_family = AF_INET; // address family Internet target.sin_port = htons(SERVER_PORT); //Port to connect on inet_pton(AF_INET, IPAddress, &(target.sin_addr.s_addr)); // target IP //-------------------------------------------------------- // ---- create SOCKET-------------------------------------- s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket if (s == INVALID_SOCKET) { printf("socket error %ld", WSAGetLastError()); WSACleanup(); return false; //Couldn't create the socket } //--------------------------------------------------------- //---- try CONNECT ----------------------------------------- if (connect(s, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR) { printf("connect error %ld", WSAGetLastError()); WSACleanup(); return false; //Couldn't connect } //protocol test send(s, "hello", 5, 0); //recieve bytes from server int n; n = recv(s, buf, 50, 0); buf[n] = 0; // make a string printf("%s\n", buf); //---- SEND bytes ------------------------------------------- gets_s(buf, 99); send(s, buf, strlen(buf), 0); // use "send" in windows if (strcmp(buf, "download") == 0) download(s, n, buf); else if (strcmp(buf, "upload") == 0) upload(s, n, buf); else { printf("protocol error"); bytesSent = send(s, "protocol error try again", 20, 0); } //-------------------------------------------------------- closesocket(s); WSACleanup(); return 0; }
업로드하는 코드입니다.
윈도우(클라이언트)에서 리눅스(서버)에다가 자신의 파일을 업로드할 수 있게끔 만들었습니다.
그런데 서버에 파일은 생성되지만 내용물은 써지지 않습니다.
질문1 ) select함수로 윈도우가 send()하는 것을 인식하여 위 코드가 작동할 수 있을까요?
질문2 ) receivefile()함수에서 printf가 왜 출력되지 않을까요? for문을 아에 안들어가는 것 같습니다ㅠ
허접한 질문 죄송합니다
( _ _ )
Forums:
루프 카운트의 초기화를 확인해봐야 할 것으로 보입니다
루프 카운트의 초기화를 확인해봐야 할 것으로 보입니다.
cnt가 초기화 되지 않으면 어떻게 되는지 확인이 필요할 것으로 보입니다.
댓글 달기