求救:关于socket 分包的解决办法
// Server.cpp : create a console application, and include the sources in the project//// 1. open the *.c in the Visual C++, then "rebuild all".// 2. click "yes" to create a project workspace.// 3. You need to -add the library 'ws2_32.lib' to your project // (Project -> Properties -> Linker -> Input -> Additional Dependencies) // 4. recompile the source.#include "stdafx.h"#include <winsock2.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <process.h>#define DEFAULT_PORT 5019int find(char s[],char t[]);void accept_conn(void *dummy);SOCKET sock,new_socket;int main(int argc, char **argv){ int addr_len; struct sockaddr_in local, client_addr; WSADATA wsaData; if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){ // stderr: standard error are printed to the screen. fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError()); //WSACleanup function terminates use of the Windows Sockets DLL. WSACleanup(); return -1; } // Fill in the address structure local.sin_family = AF_INET; local.sin_addr.s_addr = INADDR_ANY; local.sin_port = htons(DEFAULT_PORT); sock = socket(AF_INET,SOCK_STREAM, 0); //TCp socket if (sock == INVALID_SOCKET){ fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR){ fprintf(stderr, "bind() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } //waiting for the connections if (listen(sock, 5) == SOCKET_ERROR){ fprintf(stderr, "listen() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } printf("Waiting for the connections ........\n"); int connecting=1; while(connecting==1) { addr_len = sizeof(client_addr); new_socket=accept(sock, (struct sockaddr*)&client_addr, &addr_len); if (new_socket == INVALID_SOCKET){ fprintf(stderr, "accept() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } printf("accepted connection from %s, port %d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port)); _beginthread(accept_conn, 0,NULL); //Sleep(1000); }//while loop _endthread(); closesocket(sock); WSACleanup();} int find(char s[],char t[] ){ int j=0; for (int i=0;s[i]!='\0';i++) { if (t[0]==s[i]) { while (t[j]!='\0'&&s[i+j]!='\0') { j++; if (t[j]!=s[i+j]) { break; } } } if (t[j]=='\0') { return i; } } return -1;}void accept_conn(void *dummy) { // doing something here char szBuff[100000]; char szBuff2[100000]; char found[100000]; char buf[100000]; char *p; char *temp; int msg_len; int addr_len; bool again=true; struct sockaddr_in local, client_addr; SOCKET thread_socket=new_socket;while(again){ msg_len = recv(thread_socket, szBuff, sizeof(szBuff), 0); if (msg_len == SOCKET_ERROR){ fprintf(stderr, "recv() failed with error %d\n", WSAGetLastError()); WSACleanup(); //return -1; } if (msg_len == 0){ printf("Client closed connection\n"); closesocket(thread_socket); //return -1; } //printf("Bytes Received: %d, message: %s from %s\n", msg_len, szBuff, inet_ntoa(client_addr.sin_addr)); if(szBuff[0]=='b'&&szBuff[1]=='y'&&szBuff[2]=='e'){ again=false; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// szBuff2[0]='\0'; found[0]='\0'; buf[0]='\0'; FILE *fpin; if((fpin=fopen("Course.txt","r"))==NULL){ printf("Cann't open this file!\n"); } while (!feof(fpin)){ fgets(buf, 100000, fpin); char data1[100000],data2[100000],data3[100000],data4[100000]; int session=0; for (p = strtok(buf, "||"); p; p = strtok(NULL, "||")) { //printf("%s ", p); if(session==0){ temp=p; int index=0; while(*temp!='\0'){ data1[index]=*temp++; index++;} data1[index]='\0'; }else if(session==1){ temp=p; int index=0; while(*temp!='\0'){ data2[index]=*temp++; index++;} data2[index]='\0'; }else if(session==2){ temp=p; int index=0; while(*temp!='\0'){ data3[index]=*temp++; index++;} data3[index]='\0'; }else if(session==3){ temp=p; int index=0; while(*temp!='\0'){ data4[index]=*temp++; index++;} data4[index]='\0'; } session++; } int intPOs1=find(data1,szBuff); int intPOs2=find(data2,szBuff); int intPOs3=find(data3,szBuff); if(intPOs1>=0||intPOs2>=0||intPOs3>=0){ char courseCode[10000]="Course Code:"; char courseName[10000]="\nCourse Name:"; char instructor[10000]="\nCourse Instructor:"; char time[10000]="\nTime Table:"; strcat(found,courseCode); strcat(found,data1); strcat(found,courseName); strcat(found,data2); strcat(found,instructor); strcat(found,data3); strcat(found,time); strcat(found,data4); printf("%s \n", found); strcat(szBuff2,found); printf("this is szBuff2::::%s \n", szBuff2); found[0]='\0'; } } fclose(fpin); //printf("input character string:\n"); //gets(szBuff2); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// msg_len = send(thread_socket, szBuff2, sizeof(szBuff2), 0); if (msg_len == 0){ printf("Client closed connection\n"); closesocket(thread_socket); //return -1; } }closesocket(thread_socket);_endthread();}
// Client.cpp : Defines the entry point for the console application.//// 1. open the *.c in the Visual C++, then "rebuild all".// 2. click "yes" to create a project workspace.// 3. You need to -add the library 'ws2_32.lib' to your project // (Project -> Properties -> Linker -> Input -> Additional Dependencies) // 4. recompile the source.#include "stdafx.h"#include <winsock2.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#define DEFAULT_PORT 5019int main(int argc, char **argv){ char szBuff[100000]; char szBuff2[100000]; int again=1; int msg_len; //int addr_len; struct sockaddr_in server_addr; struct hostent *hp; SOCKET connect_sock; WSADATA wsaData; char *server_name = "localhost"; unsigned short port = DEFAULT_PORT; unsigned int addr; if (argc != 3){ printf("echoscln [server name] [port number]\n"); return -1; } else{ server_name = argv[1]; port = atoi(argv[2]); } if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){ // stderr: standard error are printed to the screen. fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError()); //WSACleanup function terminates use of the Windows Sockets DLL. WSACleanup(); return -1; } if (isalpha(server_name[0])) hp = gethostbyname(server_name); else{ addr = inet_addr(server_name); hp = gethostbyaddr((char*)&addr, 4, AF_INET); } if (hp==NULL) { fprintf(stderr, "Cannot resolve address: %d\n", WSAGetLastError()); WSACleanup(); return -1; } //copy the resolved information into the sockaddr_in structure memset(&server_addr, 0, sizeof(server_addr)); memcpy(&(server_addr.sin_addr), hp->h_addr, hp->h_length); server_addr.sin_family = hp->h_addrtype; server_addr.sin_port = htons(port); connect_sock = socket(AF_INET,SOCK_STREAM, 0); //TCp socket if (connect_sock == INVALID_SOCKET){ fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } printf("Client connecting to: %s\n", hp->h_name); if (connect(connect_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR){ fprintf(stderr, "connect() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } while(again==1){ printf("input character string:\n"); gets(szBuff); if(szBuff[0]=='b'&&szBuff[1]=='y'&&szBuff[2]=='e'){ again=0; } msg_len = send(connect_sock, szBuff, sizeof(szBuff), 0); if (msg_len == SOCKET_ERROR){ fprintf(stderr, "send() failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } if (msg_len == 0){ printf("server closed connection\n"); closesocket(connect_sock); WSACleanup(); return -1; } msg_len = recv(connect_sock, szBuff2, sizeof(szBuff2), 0); if (msg_len == SOCKET_ERROR){ fprintf(stderr, "send() failed with error %d\n", WSAGetLastError()); closesocket(connect_sock); WSACleanup(); return -1; } if (msg_len == 0){ printf("server closed connection\n"); closesocket(connect_sock); WSACleanup(); return -1; } //printf("Echo from the server %s.\n", szBuff); printf("Receive from the server %s", szBuff2); } closesocket(connect_sock); WSACleanup();}
[解决办法]
如果这个代码真的是你自己写的,分个包有什么难的。
方法:
判断一个包的大小是否大于某个阈值;
如果是,再分包,在2个子包前面和后面分包添加新的头和尾
[解决办法]
分包,好像搞得很专业。
假设待数据保存在数组中,
一个循环,每次发送固定字节数据如100Byte, 发完为止。
[解决办法]
这不是tcp的分片。只是你自己写的分包,假定你有个缓存,大小1024字节,如果要发送的大于1024字节,分多次把数据写入缓存发送,接收端也一样,缓存接收多次,把数据重新组合在一起。当然,这是非常简单的类型。
[解决办法]
操作系统本来就有TCP\IP协议栈;早处理过了;
[解决办法]
你是不是只ip层的分包?如果你想控制底层的分包情况,就需要对tcp/ip底层进行重写了