linux socket程式設計示例
===============================================
=======server.c==================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#define N 128
typedef struct sockaddr SA;
void ProcessList(int connfd)
{
char buf[N];
DIR *mydir;
struct dirent *myitem;
mydir = opendir(".");
while ((myitem = readdir(mydir)) != NULL)
{
if ((strcmp(myitem->d_name, ".") == 0) || (strcmp(myitem->d_name, "..") == 0)) continue;
strcpy(buf, myitem->d_name);
send(connfd, buf, N, 0);
}
closedir(mydir);
return;
}
void ProcessGet(int connfd, char buf[])
{
int fd, nbyte;
if ((fd = open(buf+1, O_RDONLY)) < 0)
{
fprintf(stderr, "fail to open %s : %s\n", buf+1, strerror(errno));
buf[0] = 'N';
send(connfd, buf, N, 0);
return;
}
buf[0] = 'Y';
send(connfd, buf, N, 0);
while ((nbyte = read(fd, buf, N)) > 0)
{
send(connfd, buf, nbyte, 0);
}
close(fd);
return;
}
void ProcessPut(int connfd, char buf[])
{
int fd, nbyte;
if ((fd = open(buf+1, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
{
printf("fail to create %s on server\n", buf+1);
return;
}
while ((nbyte = recv(connfd, buf, N, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
return;
}
int main(int argc, char *argv[])
{
int listenfd, connfd;
char buf[N];
struct sockaddr_in server_addr;
// XXX:step 1 int socket(int domain, int type, int protocol);
if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr, "fail to socket : %s\n", strerror(errno));
exit(-1);
}
#ifdef _DEBUG_
printf("socket is %d\n", listenfd);
#endif
// XXX:step 2 int bind(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(7008);
//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(listenfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
perror("fail to bind");
exit(-1);
}
listen(listenfd, 5);
while ( 1 )
{
if ((connfd = accept(listenfd, NULL, NULL)) < 0)
{
perror("fail to accept");
break;
}
recv(connfd, buf, N, 0);
switch (buf[0])
{
case 'L' :
ProcessList(connfd);
break;
case 'G' :
ProcessGet(connfd, buf);
break;
case 'P' :
ProcessPut(connfd, buf);
break;
}
close(connfd);
}
return 0;
}
=============================================================
=========client.c===============================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
//#include <string.h>
//#include <netdb.h>
#define N 128
typedef struct sockaddr SA;
void PrintHelp()
{
printf("help : display help info\n");
printf("list : get file list of server\n");
printf("get : get <file>\n");
printf("put : put <file>\n");
printf("quit : quit the client\n");
return;
}
void ProcessList(struct sockaddr_in server_addr)
{
int sockfd, nbyte;
char buf[N];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to list\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_1;
}
strcpy(buf, "L");
send(sockfd, buf, N, 0);
while ((nbyte = recv(sockfd, buf, N, 0)) != 0)
{
printf("%s\n", buf);
}
ERROR_1:
close(sockfd);
return;
}
void ProcessGet(struct sockaddr_in server_addr, char command[])
{
int sockfd, nbyte, fd;
char buf[N];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to get\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_2;
}
sprintf(buf, "G%s", command+4);
send(sockfd, buf, N, 0);
recv(sockfd, buf, N, 0);
if (buf[0] == 'N') // no such file
{
printf("No such file on server\n");
goto ERROR_2;
}
if ((fd = open(command+4, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
{
printf("fail to create local file %s\n", command+4);
goto ERROR_2;
}
while ((nbyte = recv(sockfd, buf, N, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
ERROR_2:
close(sockfd);
return;
}
void ProcessPut(struct sockaddr_in server_addr, char command[])
{
int sockfd, fd, nbyte;
char buf[N];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to get\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_3;
}
if ((fd = open(command+4, O_RDONLY)) < 0)
{
printf("fail to open %s\n", command+4);
goto ERROR_3;
}
sprintf(buf, "P%s", command+4);
send(sockfd, buf, N, 0);
while ((nbyte = read(fd, buf, N)) > 0)
{
send(sockfd, buf, nbyte, 0);
}
close(fd);
ERROR_3:
close(sockfd);
return;
}
int main(int argc, char *argv[])
{
int sockfd, fd, nbyte;
char command[32];
struct sockaddr_in server_addr;
//struct hostent *he;
if (argc < 3)
{
printf("Usage : %s <server_ip> : <port>\n", argv[0]);
exit(-1);
}
// XXX:step 1 int socket(int domain, int type, int protocol);
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr, "fail to socket : %s\n", strerror(errno));
exit(-1);
}
#ifdef _DEBUG_
printf("socket is %d\n", sockfd);
#endif
/* 取得主機資訊 */
//if ((he=gethostbyname(argv[1])) == NULL)
//{
/* 如果gethostbyname()發生錯誤,則顯示錯誤資訊並退出 */
//herror("gethostbyname");
//exit(1);
//}
// XXX:step 2 int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
//server_addr.sin_port = htons(4000);
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
//server_addr.sin_addr = *((struct in_addr *)he->h_addr);
//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
while ( 1 )
{
printf("<client> ");
fgets(command, 32, stdin);
command[strlen(command)-1] = '\0'; // overwrite the '\n'
if (strcmp(command, "help") == 0)
{
PrintHelp();
}
else if (strcmp(command, "list") == 0)
{
ProcessList(server_addr);
}
else if (strncmp(command, "get ", 4) == 0)
{
ProcessGet(server_addr, command);
}
else if (strncmp(command, "put ", 4) == 0)
{
ProcessPut(server_addr, command);
}
else if (strcmp(command, "quit") == 0)
{
printf("Bye\n");
break;
}
else
{
printf("wrong command, 'help' for command list\n");
}
}
return 0;
}