[代码] c代码 server部分
001 |
server.c |
002 |
|
003 |
====================================================================
|
004 |
|
005 |
#include <netinet/in.h> // for sockaddr_in
|
006 |
#include <sys/types.h> // for socket
|
007 |
#include <sys/socket.h> // for socket
|
008 |
#include <stdio.h> // for printf
|
009 |
#include <stdlib.h> // for exit
|
010 |
#include <string.h> // for bzero
|
011 |
/* |
012 |
#include <sys/types.h> |
013 |
#include <sys/stat.h> |
014 |
#include <fcntl.h> |
015 |
#include <unistd.h> |
016 |
*/ |
017 |
#define HELLO_WORLD_SERVER_PORT 6666
|
018 |
#define LENGTH_OF_LISTEN_QUEUE 20
|
019 |
#define BUFFER_SIZE 1024
|
020 |
#define FILE_NAME_MAX_SIZE 512
|
021 |
|
022 |
int
main( int argc,
char **argv)
|
023 |
{ |
024 |
//设置一个socket地址结构server_addr,代表服务器internet地址, 端口
|
025 |
struct
sockaddr_in server_addr; |
026 |
bzero(&server_addr, sizeof (server_addr));
//把一段内存区的内容全部设置为0 |
027 |
server_addr.sin_family = AF_INET;
|
028 |
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
|
029 |
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
|
030 |
|
031 |
//创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
|
032 |
int
server_socket = socket(PF_INET,SOCK_STREAM,0); |
033 |
if ( server_socket < 0)
|
034 |
{
|
035 |
printf ( "Create Socket Failed!" );
|
036 |
exit (1);
|
037 |
}
|
038 |
{ |
039 |
int
opt =1; |
040 |
setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&opt, sizeof (opt));
|
041 |
} |
042 |
|
043 |
//把socket和socket地址结构联系起来
|
044 |
if ( bind(server_socket,( struct
sockaddr*)&server_addr, sizeof (server_addr)))
|
045 |
{
|
046 |
printf ( "Server Bind Port : %d Failed!" , HELLO_WORLD_SERVER_PORT);
|
047 |
exit (1);
|
048 |
}
|
049 |
|
050 |
//server_socket用于监听
|
051 |
if
( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
|
052 |
{
|
053 |
printf ( "Server Listen Failed!" );
|
054 |
exit (1);
|
055 |
}
|
056 |
while
(1) //服务器端要一直运行
|
057 |
{
|
058 |
//定义客户端的socket地址结构client_addr
|
059 |
struct
sockaddr_in client_addr; |
060 |
socklen_t length =
sizeof (client_addr);
|
061 |
|
062 |
//接受一个到server_socket代表的socket的一个连接
|
063 |
//如果没有连接请求,就等待到有连接请求--这是accept函数的特性
|
064 |
//accept函数返回一个新的socket,这个socket(new_server_socket)用于同连接到的客户的通信
|
065 |
//new_server_socket代表了服务器和客户端之间的一个通信通道
|
066 |
//accept函数把连接到的客户端信息填写到客户端的socket地址结构client_addr中
|
067 |
int
new_server_socket = accept(server_socket,( struct
sockaddr*)&client_addr,&length); |
068 |
if
( new_server_socket < 0) |
069 |
{
|
070 |
printf ( "Server Accept Failed!\n" );
|
071 |
break ;
|
072 |
}
|
073 |
|
074 |
char
buffer[BUFFER_SIZE]; |
075 |
bzero(buffer, BUFFER_SIZE);
|
076 |
length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
|
077 |
if
(length < 0) |
078 |
{
|
079 |
printf ( "Server Recieve Data Failed!\n" );
|
080 |
break ;
|
081 |
}
|
082 |
char
file_name[FILE_NAME_MAX_SIZE+1]; |
083 |
bzero(file_name, FILE_NAME_MAX_SIZE+1);
|
084 |
strncpy (file_name, buffer,
strlen (buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE: strlen (buffer));
|
085 |
// int fp = open(file_name, O_RDONLY);
|
086 |
// if( fp < 0 ) |
087 |
printf ( "%s\n" ,file_name);
|
088 |
FILE
* fp = fopen (file_name, "r" );
|
089 |
if (NULL == fp )
|
090 |
{
|
091 |
printf ( "File:\t%s Not Found\n" , file_name);
|
092 |
}
|
093 |
else |
094 |
{
|
095 |
bzero(buffer, BUFFER_SIZE);
|
096 |
int
file_block_length = 0; |
097 |
// while( (file_block_length = read(fp,buffer,BUFFER_SIZE))>0)
|
098 |
while ( (file_block_length =
fread (buffer, sizeof ( char ),BUFFER_SIZE,fp))>0)
|
099 |
{
|
100 |
printf ( "file_block_length = %d\n" ,file_block_length);
|
101 |
//发送buffer中的字符串到new_server_socket,实际是给客户端
|
102 |
if (send(new_server_socket,buffer,file_block_length,0)<0)
|
103 |
{
|
104 |
printf ( "Send File:\t%s Failed\n" , file_name);
|
105 |
break ;
|
106 |
}
|
107 |
bzero(buffer, BUFFER_SIZE);
|
108 |
}
|
109 |
// close(fp); |
110 |
fclose (fp);
|
111 |
printf ( "File:\t%s Transfer Finished\n" ,file_name);
|
112 |
}
|
113 |
//关闭与客户端的连接
|
114 |
close(new_server_socket);
|
115 |
}
|
116 |
//关闭监听用的socket
|
117 |
close(server_socket);
|
118 |
return
0; |
119 |
} |
[代码] c代码 client部分
001 |
client.c |
002 |
|
003 |
#include <netinet/in.h> // for sockaddr_in
|
004 |
#include <sys/types.h> // for socket
|
005 |
#include <sys/socket.h> // for socket
|
006 |
#include <stdio.h> // for printf
|
007 |
#include <stdlib.h> // for exit
|
008 |
#include <string.h> // for bzero
|
009 |
/* |
010 |
#include <sys/types.h> |
011 |
#include <sys/stat.h> |
012 |
#include <fcntl.h> |
013 |
#include <unistd.h> |
014 |
*/ |
015 |
|
016 |
#define HELLO_WORLD_SERVER_PORT 6666
|
017 |
#define BUFFER_SIZE 1024
|
018 |
#define FILE_NAME_MAX_SIZE 512
|
019 |
|
020 |
int
main( int argc,
char **argv)
|
021 |
{ |
022 |
if
(argc != 2) |
023 |
{
|
024 |
printf ( "Usage: ./%s ServerIPAddress\n" ,argv[0]);
|
025 |
exit (1);
|
026 |
}
|
027 |
|
028 |
//设置一个socket地址结构client_addr,代表客户机internet地址, 端口
|
029 |
struct
sockaddr_in client_addr; |
030 |
bzero(&client_addr, sizeof (client_addr));
//把一段内存区的内容全部设置为0 |
031 |
client_addr.sin_family = AF_INET;
//internet协议族 |
032 |
client_addr.sin_addr.s_addr = htons(INADDR_ANY); //INADDR_ANY表示自动获取本机地址
|
033 |
client_addr.sin_port = htons(0);
//0表示让系统自动分配一个空闲端口 |
034 |
//创建用于internet的流协议(TCP)socket,用client_socket代表客户机socket
|
035 |
int
client_socket = socket(AF_INET,SOCK_STREAM,0); |
036 |
if ( client_socket < 0)
|
037 |
{
|
038 |
printf ( "Create Socket Failed!\n" );
|
039 |
exit (1);
|
040 |
}
|
041 |
//把客户机的socket和客户机的socket地址结构联系起来
|
042 |
if ( bind(client_socket,( struct
sockaddr*)&client_addr, sizeof (client_addr)))
|
043 |
{
|
044 |
printf ( "Client Bind Port Failed!\n" );
|
045 |
exit (1);
|
046 |
}
|
047 |
|
048 |
//设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
|
049 |
struct
sockaddr_in server_addr; |
050 |
bzero(&server_addr, sizeof (server_addr));
|
051 |
server_addr.sin_family = AF_INET;
|
052 |
if (inet_aton(argv[1],&server_addr.sin_addr) == 0)
//服务器的IP地址来自程序的参数 |
053 |
{
|
054 |
printf ( "Server IP Address Error!\n" );
|
055 |
exit (1);
|
056 |
}
|
057 |
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
|
058 |
socklen_t server_addr_length =
sizeof (server_addr);
|
059 |
//向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接
|
060 |
if (connect(client_socket,( struct
sockaddr*)&server_addr, server_addr_length) < 0) |
061 |
{
|
062 |
printf ( "Can Not Connect To %s!\n" ,argv[1]);
|
063 |
exit (1);
|
064 |
}
|
065 |
|
066 |
char
file_name[FILE_NAME_MAX_SIZE+1]; |
067 |
bzero(file_name, FILE_NAME_MAX_SIZE+1);
|
068 |
printf ( "Please Input File Name On Server:\t" );
|
069 |
scanf ( "%s" , file_name);
|
070 |
|
071 |
char
buffer[BUFFER_SIZE]; |
072 |
bzero(buffer,BUFFER_SIZE);
|
073 |
strncpy (buffer, file_name,
strlen (file_name)>BUFFER_SIZE?BUFFER_SIZE: strlen (file_name));
|
074 |
//向服务器发送buffer中的数据
|
075 |
send(client_socket,buffer,BUFFER_SIZE,0);
|
076 |
|
077 |
// int fp = open(file_name, O_WRONLY|O_CREAT);
|
078 |
// if( fp < 0 ) |
079 |
FILE
* fp = fopen (file_name, "w" );
|
080 |
if (NULL == fp )
|
081 |
{
|
082 |
printf ( "File:\t%s Can Not Open To Write\n" , file_name);
|
083 |
exit (1);
|
084 |
}
|
085 |
|
086 |
//从服务器接收数据到buffer中
|
087 |
bzero(buffer,BUFFER_SIZE);
|
088 |
int
length = 0; |
089 |
while ( length = recv(client_socket,buffer,BUFFER_SIZE,0))
|
090 |
{
|
091 |
if (length < 0)
|
092 |
{
|
093 |
printf ( "Recieve Data From Server %s Failed!\n" , argv[1]);
|
094 |
break ;
|
095 |
}
|
096 |
// int write_length = write(fp, buffer,length);
|
097 |
int
write_length = fwrite (buffer, sizeof ( char ),length,fp);
|
098 |
if
(write_length<length) |
099 |
{
|
100 |
printf ( "File:\t%s Write Failed\n" , file_name);
|
101 |
break ;
|
102 |
}
|
103 |
bzero(buffer,BUFFER_SIZE);
|
104 |
}
|
105 |
printf ( "Recieve File:\t %s From Server[%s] Finished\n" ,file_name, argv[1]);
|
106 |
|
107 |
close(fp);
|
108 |
//关闭socket
|
109 |
close(client_socket);
|
110 |
return
0; |
111 |
} |
[代码] open等,fopen等说明
01 |
某些注释部分,open,read,write被 fopen , fread , fwrite 替换。
|
02 |
|
03 |
说明一下: |
04 |
fopen ,
fclose ,
fread , fwrite ,
fgetc ,
fgets , fputc ,
fputs ,
freopen , fseek ,
ftell ,
rewind 等 |
05 |
缓冲文件系统 |
06 |
缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,
|
07 |
从磁盘文件将数据先读入内存“缓冲区”, 装满后再从内存“缓冲区”依此读入接收的变量。执行写文件的
|
08 |
操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存
|
09 |
“缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,
|
10 |
执行速度就快、效率高。一般来说,文件“缓冲区”的大小随机器 而定。
|
11 |
|
12 |
open, close, read, write, getc ,
getchar ,
putc , putchar
等 |
13 |
非缓冲文件系统 |
14 |
非缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符、
|
15 |
字符串、格式化数据,也可以读写二进制数 据。非缓冲文件系统依赖于操作系统,通过操作系统的功能对
|
16 |
文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度快,
|
17 |
由于ANSI标准不再包括非缓冲文件系统,因此建议大家最好不要选择它。
|
18 |
|
19 |
open等属于低级IO, |
20 |
fopen 等是高级IO。
|
21 |
|
22 |
open等返回一个文件描述符(用户程序区的), |
23 |
fopen 等返回一个文件指针。
|
24 |
|
25 |
open等无缓冲, fopen 等有缓冲。
|
26 |
|
27 |
fopen 等是在open等的基础上扩充而来的,在大多数情况下,用 fopen 等。
|
28 |
|
29 |
open 是系统调用 返回的是文件句柄,文件的句柄是文件在文件描述符表里的索引,
|
30 |
fopen 是C的库函数,返回的是一个指向文件结构的指针。 |