user-0 提问: socket套接字传输问题

回复:
user: user-1
content: server  #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <sys/stat.h> #include <errno.h>  // Need to link with Ws2_32.lib #pragma comment(lib, "ws2_32.lib")   #define PORT 6500  typedef struct file_trans_header { 	unsigned short status;// 1:OK, 0:NG 	unsigned long filesize; 	char filename[256];//file name 	char errinfo[256]; }file_trans_header_t;  int main(void) {  	//---------------------- 	// Initialize Winsock 	WSADATA wsaData; 	int iResult = 0;  	SOCKET ListenSocket = INVALID_SOCKET; 	SOCKET AcceptSocket = INVALID_SOCKET; 	sockaddr_in service, client; 	file_trans_header_t fheader;  	struct _stat info; 	 	FILE* fp = NULL; 	int len = 0;  	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 	if (iResult != NO_ERROR) { 		printf("WSAStartup() failed with error: %d\n", iResult); 		return 1; 	} 	//---------------------- 	// Create a SOCKET for listening for incoming connection requests. 	ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 	if (ListenSocket == INVALID_SOCKET) { 		printf("socket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	} 	//---------------------- 	// The sockaddr_in structure specifies the address family, 	// IP address, and port for the socket that is being bound. 	service.sin_family = AF_INET; 	service.sin_addr.s_addr = inet_addr("127.0.0.1"); 	service.sin_port = htons(PORT);  	iResult = bind(ListenSocket, (SOCKADDR *)& service, sizeof (service)); 	if (iResult == SOCKET_ERROR) { 		printf("bind function failed with error %d\n", WSAGetLastError()); 		closesocket(ListenSocket); 		WSACleanup(); 		return 1; 	} 	//---------------------- 	// Listen for incoming connection requests  	// on the created socket 	if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) { 		printf("listen function failed with error: %d\n", WSAGetLastError()); 		closesocket(ListenSocket); 		WSACleanup(); 	}  	//---------------------- 	while (1) { 		printf("\n\n*** waiting for client to connect...\n"); 		// Accept the connection. 		len = sizeof(sockaddr_in); 		AcceptSocket = accept(ListenSocket, (sockaddr*)&client, &len); 		if (AcceptSocket == INVALID_SOCKET) { 			printf("accept failed with error: %ld\n", WSAGetLastError()); 			closesocket(ListenSocket); 			WSACleanup(); 			return 1; 		} 		else 			printf("=== client [%s] connected.\n", inet_ntoa(client.sin_addr));  		//  Recive the Reuquest File Name 		memset(&fheader, 0x00, sizeof(fheader)); 		iResult = recv(AcceptSocket, fheader.filename, 255, 0); 		if (iResult > 0) 			printf("=== client want to download file [%s]\n", fheader.filename); 		else if (iResult == 0) { 			printf("=== clinet connection closed\n"); 			continue; 		} 		else { 			printf("recv failed: %d\n", WSAGetLastError()); 			closesocket(ListenSocket); 			WSACleanup(); 			return 1; 		}   		// parse the request file info 		iResult = _stat(fheader.filename, &info); 		// Check if statistics are valid:  		if (iResult != 0) 		{ 			fheader.status = htons(0); //NG 			switch (errno) 			{ 			case ENOENT: 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "File not found."); 				break; 			case EINVAL: 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "Invalid parameter to _stat."); 				break; 			default: 				/* Should never be reached. */ 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "Unexpected error %d in _stat.", errno); 				break; 			} 			printf("=== %s\n", fheader.errinfo); 		} 		else { 			fp = fopen(fheader.filename, "rb"); 			if (NULL == fp) { 				fheader.status = htons(0); //NG 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "Open File Failed."); 				printf("=== %s\n", fheader.errinfo); 			} 			else { 				fheader.status = htons(1);//OK 				fheader.filesize = htonl(info.st_size); 			} 		}  		//send protocol header 		iResult = send(AcceptSocket, (char*)&fheader, sizeof(fheader), 0); 		if (SOCKET_ERROR == iResult) { 			printf("send failed, errno = %d\n", WSAGetLastError()); 			closesocket(ListenSocket); 			WSACleanup(); 			return 1; 		}  		// send file 		if (fheader.status != 0) { 			char buff[2048]; 			printf("=== send file to client ..."); 			while (!feof(fp)) { 				iResult = fread(buff, 1, 2048, fp); 				send(AcceptSocket, buff, iResult, 0); 			} 			fclose(fp); 			printf("[done]\n"); 			shutdown(AcceptSocket, SD_SEND); 			closesocket(AcceptSocket); 		} 	}  	// No longer need server socket 	closesocket(ListenSocket); 	WSACleanup(); 	return 0; }     client  #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h>  // Need to link with Ws2_32.lib #pragma comment(lib, "ws2_32.lib")  #define SERVER_IP "127.0.0.1" #define PORT 6500  typedef struct file_trans_header { 	unsigned short status;// 1:OK, 0:NG 	unsigned long filesize; 	char filename[256];//file name 	char errinfo[256]; }file_trans_header_t;   int main(void) { 	//---------------------- 	// Initialize Winsock 	WSADATA wsaData; 	file_trans_header_t fheader;  	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 	if (iResult != NO_ERROR) { 		printf("WSAStartup function failed with error: %d\n", iResult); 		return 1; 	} 	//---------------------- 	// Create a SOCKET for connecting to server 	SOCKET ConnectSocket; 	ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 	if (ConnectSocket == INVALID_SOCKET) { 		wprintf(L"socket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	} 	//---------------------- 	// The sockaddr_in structure specifies the address family, 	// IP address, and port of the server to be connected to. 	sockaddr_in clientService; 	clientService.sin_family = AF_INET; 	clientService.sin_addr.s_addr = inet_addr(SERVER_IP); 	clientService.sin_port = htons(PORT);  	//---------------------- 	// Connect to server. 	iResult = connect(ConnectSocket, (SOCKADDR *)& clientService, sizeof (clientService)); 	if (iResult == SOCKET_ERROR) { 		printf("connect function failed with error: %ld\n", WSAGetLastError()); 		iResult = closesocket(ConnectSocket); 		if (iResult == SOCKET_ERROR) 			printf("closesocket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	}  	printf("=== connected to server.\n");  		char filename[512] = { 0 }; 		printf("\n\n*** please input the filename(with path) you want to download:\n"); 		scanf("%s", filename); 		//send file name to server 		iResult = send(ConnectSocket, filename, (int)strlen(filename), 0); 		if (iResult == SOCKET_ERROR) { 			printf("send failed: %d\n", WSAGetLastError()); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		// shutdown the connection since no more data will be sent 		iResult = shutdown(ConnectSocket, SD_SEND); 		if (iResult == SOCKET_ERROR) { 			printf("shutdown failed: %d\n", WSAGetLastError()); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		// Receive the header 		int recvbuflen = sizeof(fheader); 		memset(&fheader, 0x00, recvbuflen);  		iResult = recv(ConnectSocket, (char*)&fheader, recvbuflen, 0); 		if (ntohs(fheader.status) == 0) { 			printf("%s\n", fheader.errinfo); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		char* name = strrchr(fheader.filename, '\\'); 		if (NULL == name) { 			name = fheader.filename; 		} 		else { 			name++; 		}  		FILE* fp = fopen(name, "wb"); 		if (NULL == fp) { 			printf("fopen failed\n"); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		char recvbuf[2048]; 		unsigned long filesize = 0; 		recvbuflen = 2048; 		do { 			iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); 			if (iResult > 0) { 				filesize += iResult; 				fwrite(recvbuf, 1, iResult, fp); 			} 			else if (iResult == 0)  				printf("=== download is done\n"); 			else 				printf("recv failed: %d\n", WSAGetLastError());  		} while (iResult > 0); 		fclose(fp);  		if (filesize != ntohl(fheader.filesize)) 		{ 			printf("=== file download error, mismatch filesize\n"); 		}   	iResult = closesocket(ConnectSocket); 	if (iResult == SOCKET_ERROR) { 		wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	}  	WSACleanup(); 	return 0; }

user: user-2
content: 不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

user: user-3
content: 引用 4 楼 qq423399099 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  不如打log来的实际，   我们以前测试代码（是测试人员， 通过抓包或者查看日志，来验证 协议设计、实现的正确性）   调试这种玩意， 取决于程序员，测试人员搞不了，

user: user-4
content: 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

user: user-5
content: 不知道是不是因为你的服务端程序默认使用的是Nagle算法。在服务端程序加入下面代码试下 const char chOpt=1;        int   nErr=setsockopt(   m_socket,   IPPROTO_TCP,   TCP_NODELAY,   &chOpt,   sizeof(char));

user: user-0
content: 跟题有关？？希望讲详细一点，谢了

user: user-6
content: 楼主，学会打印日志，   recv 打印接受的数据，