最近再做一个东西,涉及到了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"); } }
代码关键部分已经注释不懂可以进行跟帖回复!
作者:MHapdream 发表于2013-5-15 11:02:32 原文链接
阅读:0 评论:0 查看评论