客户端与服务器端通信流程
客户端Linux
建立socket
确定服务器scokaddr_in结构体
点分十进制IP转换
使用connect连接
打开文件
准备缓冲区
缓冲区初始化置空
将文件内容读入缓冲区
使用send将缓冲区内容发送到服务器
文件内容发送完成
关闭文件
关闭socket
服务器 Windows
添加winsock头文件
初始化WSAStartup
建立socket
确定服务器scokaddr_in结构体
点分十进制IP转换
使用bind绑定套接字
使用listen监听
使用accept接受连接请求
accept返回新的套接字描述符
使用recv接收传来的数据(文件路径)
打开文件,这里需要文件名
从该字符串获取文件名
使用recv接收文件内容
判断recv函数返回的状态
将接收到的内容放入缓冲区
将缓冲区内容写入文件
关闭文件
WSACleanup函数
关闭socket
WINDOW下socket编程和LINUX的区别
头文件
#include <winsock2.h>
初始化
windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragma comment(lib,"Ws2_32")来告知编译器链接该lib。linux下不需要
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );
1)wVersionRequested是Windows Sockets API提供的调用方可使用的最高版本号。
2)lpWSAData 是指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。假如一个程序要使用2.1版本的Socket,那么程序代码如下
wVersionRequested = MAKEWORD( 2, 1 );
WSACleanup函数
int WSACleanup (void);
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统
关闭socket
windows下closesocket(...)
linux下close(.…
获取错误码
windows下getlasterror()/WSAGetLastError()
linux下,未能成功执行的socket操作会返回-1;如果包含了errno.h,就会设置errno变量
LINUX和WINDOWS下sockaddr_in结构体的区别
Linux:
struct sockaddr_in
{
u_short sin_family;//2B
u_short sin_port;//2B
struct in_addr sin_addr;//4B
char sin_zero[8];//8B
}
Windows:
struct SOCKADDR_IN {
short int sin_family; //2B
unsigned short int sin_port; //2B端口(使用网络字节顺序)
struct IN_ADDR sin_addr; //4B IP地址,是个结构
unsigned char sin_zero[8]; //8B
};
其他的一些小细节
在Windows中
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)
在Linux中
connect(sockcd,(struct sockaddr*)&server,sizeof(server))
在C和C++中文件的创建函数是不一样的,不要弄错了
Windows和Linux中的sleep函数
Windows中Sleep函数S大写,Linux中sleep函数s小写
Windows中头文件是#include <windows.h>
Linux中头文件是#include <unistd.h>
Linux中将IP地址赋值给IP地址结构体
if(inet_pton(AF_INET,"192.168.0.13",&server.sin_addr)<0)
{
printf("inet_pton error!\n");
}
Windows中赋值
server.sin_addr.s_addr= inet_addr("192.168.0.13");
WINDOWS作为服务器端的代码
#include <winsock2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib") //add ws2_32.lib
#define MAXLINE 4096
#define BUFFER_SIZE 1024
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err,iLen;
SOCKET sockSrv;
wVersionRequested = MAKEWORD(2,2);
char filename[100];
char filepath[100];
char *buffer;//file buffer
int fileTrans;
int lenfilepath;
FILE *fp;
int writelength;
buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
//bzero(buffer,BUFFER_SIZE);
memset(buffer,0,sizeof(buffer));
if(WSAStartup(wVersionRequested,&wsaData)!=0)
{
printf("WSAStartup error!\n");
return -1;
}
if(( sockSrv =socket(AF_INET,SOCK_STREAM,0))<0){
printf("socket error!\n");
return -2;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);
addrSrv.sin_port = htons(9000);
if(bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))!=0)
{
printf("bind error!\n");
return -3;
}
if(listen(sockSrv,5)!=0)
{
printf("listen error!\n");
return -4;
}
printf("Sever build finished ...\n");
while(1)
{
SOCKET temp;
if((temp = accept(sockSrv,(SOCKADDR*)NULL,NULL))>0)
{
//printf("client IP: %d\n",ntohl(client.sin_addr.s_addr));
//printf("client PORT: %d\n",ntohs(client.sin_port));
memset(filename,'\0',sizeof(filename));
memset(filepath,'\0',sizeof(filepath));
lenfilepath = recv(temp,filepath,100,0);
printf("filepath :%s\n",filepath);
if(lenfilepath<0)
{
printf("recv error!\n");
}
else
{
int i=0,k=0;
for(i=strlen(filepath);i>=0;i--)
{
if(filepath[i]!='/')
{
k++;
}
else
break;
}
strcpy(filename,filepath+(strlen(filepath)-k)+1);
}
printf("filename :%s\n",filename);
fp = fopen(filename,"w");
if(fp!=NULL)
{
while(fileTrans =recv(temp,buffer,BUFFER_SIZE,0))
{
if(fileTrans<0)
{
printf("recv error!\n");
break;
}
writelength = fwrite(buffer,sizeof(char),fileTrans,fp);
if(writelength <fileTrans)
{
printf("write error!\n");
break;
}
//bzero(buffer,BUFFER_SIZE);
memset(buffer,'\0',sizeof(buffer));
}
printf("recv finished!\n");
fclose(fp);
}
else
{
printf("filename is null!\n");
}
closesocket(temp);
}
else
{
printf("accept error!\n");
closesocket(temp);
}
}
closesocket(sockSrv);
WSACleanup();
return 0;
}
LINUX作为客户端的代码
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <memory.h>
#include <stdlib.h> //for malloc
#define BUFFER_SIZE 1024
int main()
{
int sockcd;
struct sockaddr_in server;
char filepath[100];//file to translate
FILE *fp;
int lenpath; //filepath length
char *buffer;//file buffer
int fileTrans;
buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
bzero(buffer,BUFFER_SIZE);
//memset(buffer,0,sizeof(buffer));
if((sockcd = socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("socket build error!\n");
}
memset(&server,0,sizeof(server));
server.sin_family= AF_INET;
server.sin_port = htons(9000);
if(inet_pton(AF_INET,"192.168.0.13",&server.sin_addr)<0)
{
printf("inet_pton error!\n");
}
if(connect(sockcd,(struct sockaddr*)&server,sizeof(server))<0)
{
printf("connect error!\n");
}//connect with server
printf("file path:\n");
scanf("%s",filepath);//get filepath
fp = fopen(filepath,"r");//opne file
if(fp==NULL)
{
printf("filepath not found!\n");
return 0;
}
printf("filepath : %s\n",filepath);
lenpath = send(sockcd,filepath,strlen(filepath),0);// put file path to sever
if(lenpath<0)
{
printf("filepath send error!\n");
}
else
{
printf("filepath send success!\n");
}
sleep(3);
while((fileTrans = fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0)
{
printf("fileTrans =%d\n",fileTrans);
if(send(sockcd,buffer,fileTrans,0)<0)
{
printf("send failed!\n");
break;
}
bzero(buffer,BUFFER_SIZE);
//memset(buffer,0,sizeof(buffer));
}
fclose(fp);
close(sockcd);
return 0;
}
更多推荐
WINDOW与LINUX的TCP/IP通信
发布评论