Socket:java與C之間的文件傳送(C語言之間的通信)

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");
	}
}

代碼關鍵部分已經註釋不懂可以進行跟帖回覆!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章