1,这里是一个很简单的文件传输程序,从服务器端传给客户端。客户端直接输入“ok”,服务器端收到确认是“ok”就开始传输文件,一次传10个字符。因为简单很多对文件读写,socket读写错误的判断处理都没有实现。
2,服务器端代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#define SERV_PORT 9877
#define LISTENQ 3
#define MAXLINE 1024
int main(int argc,char **argv){
int listenfd,connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr,servaddr;
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket error");
exit(1);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(SERV_PORT);
if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr))==-1){
perror("bind");
exit(1);
}
if(listen(listenfd,LISTENQ)==-1){
perror("listen");
exit(1);
}
for(;;){
clilen=sizeof(cliaddr);
sleep(10);
if((connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen))==-1){
perror("accept");
exit(1);
}
if((childpid=fork())==0){
close(listenfd);
str_snd(connfd);
exit(0);
}
close(connfd);
}
}
void str_snd(int sockfd){
ssize_t n;
char buf[MAXLINE];
char snd[MAXLINE];
int fd;
while((n=read(sockfd,buf,MAXLINE))>0){ //循环读取客户端输入的字符串,直到输入“ok”。传输文件
buf[n-1]='\0';
if(strcmp(buf,"ok")==0){ //判断客户端输入的是否为“ok”
FILE *fp=fopen("abc.c","rt"); //打开当前目录的abc.c文件,这里比较简单,没有判断打开文件失败的情况。
while(1){
n=fread(buf,1,10,fp);
write(sockfd,buf,n);
if(feof(fp)){ //判断文件是否读取到末尾。
close(sockfd);
fclose(fp);
}
}
}
}
}
3,客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#define SERV_PORT 9877
#define LISTENQ 3
#define MAXLINE 1024
int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2){
printf("usage: %s <IPaddress>",argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
str_rcv(sockfd);
exit(0);
}
void str_rcv(sockfd){
ssize_t n;
FILE *fp;
char sendline[MAXLINE], recvline[MAXLINE];
//直接向服务器写入“ok”,
write(sockfd, “ok!”, 3);
fp=fopen("123.c","a+"); //以APPEND的方式打开文件。
printf("begin to recv data.........\n"); //显示开始接收数据的提示。
while(1){
again: n=read(sockfd,recvline,MAXLINE); //循环从服务器读取字符
switch(n){
case 0: //服务器端关闭套接字
printf("end recv data ....\n");
fclose(fp); //关闭文件,关闭客户端套接字
close(sockfd);
exit(1);
case -1:
goto again;
default:
printf("%s",recvline);
fwrite(recvline,1,n,fp);
}
}
}
4,问题,如果在服务器和客户端都用read,write读写套接字和文件,发现服务器端一直阻塞在read调用。