텔넷을 통해 간단한 TCP 서버에 연결할 수 있도록 기본 c 프로그램을 만들려고했습니다. 연결되면 문자열을 입력 할 수 있고 서버가이를 토글합니다.
텔넷을 사용하려고 할 때 연결을 거부합니다. 이것이 내가 입력하는 것입니다.
telnet localhost 7654
서버 터미널에서 오류가 발생하지 않고 터미널에 다음이 표시됩니다.
"서버가 시작됩니다 ..."
과
"이제 서버가 들어오는 연결을 수신하고 있습니다."
다음은 서버 코드입니다.
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<signal.h>
#include<errno.h>
#include<ctype.h>
#include <unistd.h>
#define PORTNUMBER 7654
#define BUF_LEN 512
#define COM_LEN 32
void manageConnection(int, int);
int serverProcessing(char *input, char* output);
void handle_sigcld(int);
int main()
{
int mainSocket, tempSocket;
int errorCode, clientLength;
int pid;
struct sockaddr_in server,client;
struct hostent* clientDetails;
struct sigaction cldsig;
fprintf(stderr,"The server is starting up...\n");
/* the following lines of codes are used to prevent zombie processes
from occuring. It allows each childed to be waited on. */
cldsig.sa_handler = handle_sigcld;
sigfillset(&cldsig.sa_mask);
cldsig.sa_flags = SA_RESTART | SA_NOCLDSTOP;
sigaction(SIGCHLD,&cldsig,NULL);
/* creating the socket stream, SOCK_STREAM is a connection based protocol
where a connection is established between and is only disconnected
when a party leaves or network error. */
mainSocket = socket(PF_INET, SOCK_STREAM, 0);
if (mainSocket < 0)
{
perror("Error in function socket()");
exit(EXIT_FAILURE);
}
// setting up the server details by declaring the port number, address family and interface
memset(&server,0,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = PORTNUMBER;
// binding the socket to the server details listed above
if ( (errorCode = bind(mainSocket,(struct sockaddr *)&server,sizeof(server)) ) < 0 )
{
perror("Error in function bind()\n");
exit(EXIT_FAILURE);
}
// put the socket into listen mode so it can listen for incoming connections
if ( (errorCode = listen(mainSocket,5) ) < 0 )
{
perror("Error in function listen()\n");
exit(EXIT_FAILURE);
}
fprintf(stderr,"The server is now listening for incoming connections\n");
while(1)
{
clientLength = sizeof(client);
// accept function is used to extract the first connection and returns a new file discriptor
tempSocket = accept(mainSocket,(struct sockaddr *)&client,(socklen_t *)&clientLength);
if (tempSocket < 0 )
{
perror("Error in function accept()\n");
exit(EXIT_FAILURE);
}
// printing the client connection details
clientDetails = gethostbyaddr( (void*)&client.sin_addr.s_addr,4,AF_INET);
if (clientDetails == NULL)
{
herror("Error in fetching client details\n");
exit(EXIT_FAILURE);
}
fprintf(stderr,"accepted connection from %s on port %d with discriptor %d \n",
clientDetails->h_name,ntohs(client.sin_port),tempSocket);
// this function is used to create a new process to handle the client
if ( (pid = fork() ) == 0)
{
// we close the connection to the main socket and open a sub connection with the temp socket
close(mainSocket);
manageConnection(tempSocket,tempSocket);
exit(EXIT_FAILURE);
}
else
{
close(tempSocket);
}
}
close(mainSocket);
return 0;
}
void manageConnection(int in, int out)
{
int readCount,bufCount;
char inBuf[BUF_LEN], outBuf[BUF_LEN], inData[COM_LEN], hostname[40];
char prefix[100];
char endOfData = '\n';
int i, revCount;
char revBuf[BUF_LEN];
gethostname(hostname,40);
sprintf(prefix,"\tC%d", getpid() );
fprintf(stderr,"\n%s starting up\n",prefix);
sprintf(outBuf,"\n\n connected to TCP server on host: %s \n"\
"enter X to exit otherwise enter the"\
"string to do something cool\n",hostname);
write(out,outBuf,strlen(outBuf));
while(1)
{
bufCount = 0;
while(1)
{
readCount = read(in,inData,COM_LEN);
if (readCount < 0 )
{
if ( (bufCount + readCount) > BUF_LEN)
{
fprintf(stderr,"buffer limit exceeded\n");
close(in);
exit(EXIT_FAILURE);
}
fprintf(stderr,"%sHave read in:\n",prefix);
for(i=0; i<readCount; i++)
{
fprintf(stderr,"%s%d\t%c\n",prefix,inData[i],inData[i]);
}
memcpy(&inBuf[bufCount], inData, readCount);
bufCount=bufCount+readCount;
if (inData[readCount - 1] == endOfData)
{
break;
}
}
else if (readCount == 0 )
{
fprintf(stderr,"\n%s Client has closed connection\n",prefix);
close(in);
exit(EXIT_FAILURE);
}
else
{
sprintf(prefix,"\tC %d: while reading from connection", getpid() );
perror(prefix);
close(in);
exit(EXIT_FAILURE);
}
}
inBuf[bufCount - 2] = '\0';
if (inBuf[0] == 'X')
{
break;
}
revCount = serverProcessing(inBuf,revBuf);
sprintf(outBuf," the server recieved %d characters, which when the string is processed"\
"are:\n%s\n\n enter next string:",strlen(revBuf),revBuf);
write(out,outBuf,strlen(outBuf));
}
fprintf(stderr,"\n%s client has closed the connection\n",prefix);
close(in);
}
int serverProcessing(char* input, char* output)
{
int i, len;
char c;
len=strlen(input);
for(i=0;i<len;i++)
{
c=tolower(input[i]);
if(c==input[i])
{
output[i]=toupper(input[i]);
}
else
{
output[i]=c;
}
}
output[len]='\0';
return len;
}
void handle_sigcld(int sig)
{
pid_t cld;
while ( 0 < waitpid(-1,NULL, WNOHANG) );
}
포트 번호는 네트워크 바이트 순서로 제공되어야하며 바이트 순서에 영향을받지 않도록 CPU에 해당 엔디안이 없을 수 있습니다.
server.sin_port = PORTNUMBER
으로
server.sin_port = htons(PORTNUMBER)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다