http://blog.csdn.net/mhapdream/article/details/8929253 Socket:java與C之間的文件傳送<1>(C語言之間的通信)
http://blog.csdn.net/mhapdream/article/details/8929457 Socket:java與C之間的文件傳送<2>(JAVA語言之間的通信)
http://blog.csdn.net/mhapdream/article/details/8929590 Socket:java與C之間的文件傳送<3>(JAVA與C通信需要注意的地方)
http://blog.csdn.net/mhapdream/article/details/8929638 Socket:java與C之間的文件傳送<4>(JAVA與C通信)
最近再做一個東西,涉及到了java與C socket通信方面的內容,以下是個人的一部分經歷。
我覺得要清楚C與java之間是如何通訊的首先要清楚C與C之間是如何通訊的,JAVA與JAVA之間是怎樣通訊的,java與c通信需要注意哪些地方,然後我們就可以讓java與C進行相互痛心了!
首先來看一下C與c是如何通信的
服務器:
#include<stdio.h>
#include<winsock.h>
#pragma comment (lib,"wsock32.lib")
void main()
{
WSADATA data;
WSAStartup(MAKEWORD(2,0),&data);
SOCKET socket1;
struct sockaddr_in local;
struct sockaddr_in from;
int fromlen =sizeof(from);
local.sin_family=AF_INET;
local.sin_port=htons(1000); ///監聽端口
local.sin_addr.s_addr=INADDR_ANY; ///本機
socket1=socket(AF_INET,SOCK_DGRAM,0);
bind(socket1,(struct sockaddr*)&local,sizeof local);
while (1)
{
char buffer[1024]="\0";
printf("waiting for message from others-------------\n");
if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,&fromlen)!=SOCKET_ERROR)
{
printf("Received datagram from %s--%s\n",inet_ntoa(from.sin_addr),buffer);
////給cilent發信息
sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,fromlen);
}
}
closesocket(socket1);
WSACleanup();
}
首先來看一下服務器端大概的邏輯就是1:初始化體格套接字
2.綁定端口與ip
3.進行監聽,
4.關閉套接字
客戶端:
#include<stdio.h>
#include<winsock.h>
#pragma comment (lib,"wsock32.lib")
void main()
{
WSADATA data;
WSAStartup(MAKEWORD(2,0),&data);
SOCKET socket1;
struct sockaddr_in server;
int len =sizeof(server);
server.sin_family=AF_INET;
server.sin_port=htons(1000); ///server的監聽端口
server.sin_addr.s_addr=inet_addr("???.???.???.???"); ///server的地址
socket1=socket(AF_INET,SOCK_DGRAM,0);
while (1)
{
char buffer[1024]="\0";
printf("input message\n");
scanf("%s",buffer);
if (strcmp(buffer,"bye")==0)
break;
if (sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
{
if (recvfrom(socket1,
buffer,
sizeof buffer,
0,
(struct sockaddr*)&server,&len) != SOCKET_ERROR)
printf("rece from server:%s\n",buffer);
}
}
closesocket(socket1);
WSACleanup();
}
再看一下客戶端:
首先來看一下服務器端大概的邏輯就是1:初始化體格套接字
2.綁定端口與ip
3.向服務器發送數據請求,
4.關閉套接字
瞭解了通信原理再讓我們看一下C與C語言之間用套接字是如何進行文件傳輸的呢!
服務器端
#include <WINSOCK2.H>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define SIZE 1024*8
void main()
{
//創建套接字
WORD myVersionRequest;
WSADATA wsaData;
myVersionRequest=MAKEWORD(1,1);
int err;
err=WSAStartup(myVersionRequest,&wsaData);
if (!err)
{
printf("打開連接\n");
}
else
{
//進一步綁定套接字
printf("連接打開失敗");
return;
}
SOCKET serSocket=socket(AF_INET,SOCK_STREAM,0);//創建了可識別套接字
//需要綁定的參數
SOCKADDR_IN addr;
addr.sin_family=AF_INET;
addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//ip地址
addr.sin_port=htons(6000);//綁定端口
bind(serSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR));//綁定完成
printf("綁定成功\n");
listen(serSocket,5);//其中第二個參數代表能夠接收的最多的連接數
//////////////////////////////////////////////////////////////////////////
//開始進行監聽
//////////////////////////////////////////////////////////////////////////
SOCKADDR_IN clientsocket;
int len=sizeof(SOCKADDR);
char sendBuf[50];
while(true)
{
SOCKET serConn;
serConn=accept(serSocket,(SOCKADDR*)&clientsocket,&len);//如果這裏不是accept而是conection的話就會不斷的監聽
sprintf(sendBuf,"請求IP地址爲%s",inet_ntoa(clientsocket.sin_addr));//找對對應的IP並且將這行字打印到那裏
send(serConn,sendBuf,strlen(sendBuf)+1,0);//發送請求信息
printf("客戶端已打開\n請輸入存放文件地址:\n");
FILE *fp;//定義文件指針
/* char path[100]={"0"};
int i=0;
while(path[i]!='\0')
{
if(path[i]=='/')
path[i]='\\';
i++;
}
gets(path);*/
if((fp=fopen("hehehehe.xml","wb"))==NULL)
{
printf("文件未打開\n");
printf("客戶端已打開\n請輸入存放文件地址:\n");
}
else
{
printf("文件已打開 開始文件傳輸......\n");
//發送開始標誌
send(serConn,"開始傳送",strlen("開始傳送")+1,0);
//得到文件大小
char datalength[20];
long int length=0;
// recv(serConn,datalength,21,0);
length=atol(datalength);
printf("得到文件大小: %d\n",length);
//開始傳送
double cent=0.0;
char receiveBuf[SIZE];
long int x=0;
while (1)
{
x=x+SIZE;
if(x<length)
{
cent=(double)x*100.0/(double)length;
// printf("已接收: %4.2f%\n",cent);
recv(serConn,receiveBuf,SIZE+1,0);
fwrite(receiveBuf,1,SIZE,fp);
}
else
{
recv(serConn,receiveBuf,length+SIZE-x+1,0);
printf("文件接收完畢\n");
fwrite(receiveBuf,1,length+SIZE-x,fp);
fclose(fp);
break;
}
}
}
closesocket(serConn);//關閉
}
WSACleanup();//釋放資源的操作
system("pause");
}
客戶端:
#include <WINSOCK2.H>
#include <stdio.h>
#include <time.h>
#pragma comment(lib,"ws2_32.lib")
#define SIZE 1024*8
void main()
{
FILE *fp;
int err;
int length=0;
SOCKET clientSocket;
SOCKADDR_IN clientsock_in;
char receiveBuf[100]={"0"};
char ip_addr[16]={"127.0.0.1"};
WORD versionRequired;
WSADATA wsaData;
versionRequired=MAKEWORD(1,1);
err=WSAStartup(versionRequired,&wsaData);//協議庫的版本信息
if (!err)
{
printf("客戶端嵌套字已經打開!\n");
}
else
{
printf("客戶端的嵌套字打開失敗!\n");
return;//結束
}
clientSocket=socket(AF_INET,SOCK_STREAM,0);
/*printf("請輸入主機IP:\n");
scanf("%s",ip_addr);*/
//連接服務器
clientsock_in.sin_addr.S_un.S_addr=inet_addr(ip_addr);
clientsock_in.sin_family=AF_INET;
clientsock_in.sin_port=htons(6000);
if(connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR))!=SOCKET_ERROR)//開始連接
{
recv(clientSocket,receiveBuf,101,0);
printf("%s\n",receiveBuf);
char path[100]={"0"};
int i=0;
do
{
printf("請輸入文件地址:\n");
gets(path);
while(path[i]!='\0')
{
if(path[i]=='/')
path[i]='\\';
i++;
}
i=0;
if((fp=fopen(path,"rb"))==NULL)
{
i=1;
printf("文件未打開\n");
}
}while(i);
fseek(fp,0L,SEEK_END);
length=ftell(fp);
printf("待傳送文件大小: %d\n",length);
printf("文件已經打開 等待主機消息......\n");
//得到主機開始傳送消息
recv(clientSocket,receiveBuf,101,0);
printf("%s\n",receiveBuf);
if(strcmp(receiveBuf,"開始傳送")==0)
{
//傳送文件長度
char sendBuf[20];
ltoa(length,sendBuf,10);
send(clientSocket,sendBuf,21,0);
fseek(fp,0L,SEEK_SET);
//傳送文件
long int y=0;
double cent;
char trans[SIZE];
while(!feof(fp))
{
fread(trans,1,SIZE,fp);
y=y+SIZE;
if(y<length)
{
cent=(double)y*100.0/(double)length;
// printf("已發送: %4.2f%\n",cent);
send(clientSocket,trans,SIZE+1,0);
Sleep(5);//此處的作用是防止服務器短寫文件出錯,如果不加的話會出現各種奇葩的亂碼,時間需要根據數據的大小進行等待,等待系統寫文件。當然了這裏還有更好的方法,就是寫完後向服務器再向服務器發送下次請求。
}
else
{
send(clientSocket,trans,length+SIZE-y+1,0);
closesocket(clientSocket);
WSACleanup();
}
}
fclose(fp);
}
printf("文件發送完畢\n");
system("pause");
}
else
{
printf("未能連接到服務器程序退出!\n");
}
}
代碼關鍵部分已經註釋不懂可以進行跟帖回覆!