实验课的内容,建立tcp 实现文件的传输,需要注意的一个地方就是,客户端和服务器端不要放在一起,文件可以放在客户端,绝对路径就可以。还有就是自己写一个makefile
服务端:
建立socket
使用bind绑定套接字
使用listen监听
使用accept接受连接请求 accept返回新的套接字描述符
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8789 /*侦听端口地址*/
#define BACKLOG 2 /*侦听队列长度*/
int main(int argc, char *argv[])
{
int ss,sc; /*ss为服务器的socket描述符,sc为客户端的socket描述符*/
struct sockaddr_in server_addr; /*服务器地址结构*/
struct sockaddr_in client_addr; /*客户端地址结构*/
int err; /*返回值*/
pid_t pid; /*分叉的进行ID*/
/*建立一个流式套接字*/
ss = socket(AF_INET, SOCK_STREAM, 0);
if(ss < 0){ /*出错*/
printf("socket error\n");
return -1;
}
/*设置服务器地址*/
bzero(&server_addr, sizeof(server_addr)); /*清零*/
server_addr.sin_family = AF_INET; /*协议族*/
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/
server_addr.sin_port = htons(PORT); /*服务器端口*/
/*绑定地址结构到套接字描述符*/
err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(err < 0){/*出错*/
printf("bind error\n");
return -1;
}
/*设置侦听*/
err = listen(ss, BACKLOG);
if(err < 0){ /*出错*/
printf("listen error\n");
return -1;
}
/*主循环过程*/
for(;;) {
socklen_t addrlen = sizeof(struct sockaddr);
sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen);
/*接收客户端连接*/
if(sc < 0){ /*出错*/
continue; /*结束本次循环*/
}
/*建立一个新的进程处理到来的连接*/
pid = fork(); /*分叉进程*/
if( pid == 0 ){ /*子进程中*/
process_conn_server(sc); /*处理连接*/
close(ss); /*在子进程中关闭服务器的侦听*/
return 0;
}else{
close(sc); /*在父进程中关闭客户端的连接*/
}
}
}
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 1024
/*服务器对客户端的处理*/
void process_conn_server(int s)
{
ssize_t size = 0;
char buffer[BUFFER_SIZE];
FILE *stream;
strcpy(buffer,"请输入传输的文件路径:\n");
write(s, buffer, BUFFER_SIZE);
int length=0;
char buffer_add[BUFFER_SIZE]={'\0'};
for(;;){
size = read(s, buffer, BUFFER_SIZE-length);
if(size <= 0){
return;
}
strcat(buffer_add, buffer);
length+=size;
if(length>=BUFFER_SIZE) break;
}
if((stream=fopen(buffer_add, "w"))==NULL) return;
for(;;){
size = read(s, buffer, BUFFER_SIZE);
if(size <= 0){
return;
}
int write_len=fwrite(buffer, sizeof(char), size, stream);
}
fclose(stream);
}
客户端:
建立socket
确定服务器scokaddr_in结构体 点分十进制IP转换
使用connect连接 打开文件
准备缓冲区 缓冲区初始化置空
将文件内容读入缓冲区
使用send将缓冲区内容发送到服务器
文件内容发送完成
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8888 /*侦听端口地址*/
int main(int argc, char *argv[])
{
int s; /*s为socket描述符*/
struct sockaddr_in server_addr; /*服务器地址结构*/
s = socket(AF_INET, SOCK_STREAM, 0); /*建立一个流式套接字 */
if(s < 0){ /*出错*/
printf("socket error\n");
return -1;
}
/*设置服务器地址*/
bzero(&server_addr, sizeof(server_addr)); /*清零*/
server_addr.sin_family = AF_INET; /*协议族*/
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/
server_addr.sin_port = htons(PORT); /*服务器端口*/
/*将用户输入的字符串类型的IP地址转为整型*/
inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
/*连接服务器*/
connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
process_conn_client(s); /*客户端处理过程*/
close(s); /*关闭连接*/
return 0;
}
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 1024
/*客户端的处理过程*/
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[BUFFER_SIZE];
FILE *stream;
int length=0;
char buffer_add[BUFFER_SIZE]={'\0'};
for(;;){
size = read(s, buffer, BUFFER_SIZE-length);
if(size <= 0){
return;
}
strcat(buffer_add, buffer);
length+=size;
if(length>=BUFFER_SIZE) break;
}
printf("%s", buffer_add);
scanf("%s", buffer);
write(s, buffer, BUFFER_SIZE);
if((stream=fopen(buffer, "r"))==NULL) return;
printf("ing...\n");
for(;;){
size = fread(buffer, sizeof(char), BUFFER_SIZE, stream);
if(size <= 0){
return;
}
write(s, buffer, size);
}
fclose(stream);
}