소켓 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가 초기화 되지 않으면 어떻게 되는지 확인이 필요할 것으로 보입니다.
댓글 달기