去除socket编程当中接收到的多余符\0

解决Socket编程中多余数据问题
本文探讨了在Socket编程中遇到的一个问题:客户端采用同步方式接收数据时,会额外接收到一个无关的字符。文章介绍了如何利用String.TrimEnd()方法去除这个多余字符,并附带讲解了字符串的几种常用操作。

在socket编程当中,由于本人的服务器端采取的为异步接收,所以它可以获取到准确的数据接收长度
而在客户端是采用的同步方式,从而无法获取到(应该可能有方法我没有找到),这样导致了在接收数据时
除到接收到完整的数据以外,还多出了一个无关的数据"\0",还真是苦恼.难怪程序咋测试咋不对.但也不报错.

后来找到一个投机的方式,应该说是治村不治本的方式采用,字符串的TrimEnd()方法来去除到数据最后无关的多余数据

String.TrimEnd 方法

从当前 String 对象移除数组中指定的一组字符的所有尾部匹配项。 ... 从当前 String 对象移除数组中指定的一组字符的所有尾部匹配项。 命名空间: System 程序集: mscorlib(在 mscorlib.dll 中)

eg:string result=friendUserID.TrimEnd('\0');
在此里就顺便说下了字符串的一些操作.
(以下引自MSDN)
剪裁和移除字符
如果将一个句子分析成单个的单词,则最后的结果可能是单词的一端或另一端带有空格(也称为空白)。在这种情形下,可以使用 System.String 类中的剪裁方法之一来从字符串中的指定位置移除任何数量的空格或其他字符。下表描述了可用的剪裁方法。

String.Trim

从字符串的开头和结尾处移除空白。

String.TrimEnd

从字符串的结尾处移除在字符数组中指定的字符。

String.TrimStart

从字符串的开头移除在字符数组中指定的字符。

String.Remove

从字符串中的指定索引位置移除指定数量的字符。

String MyString = " Big   ";
Console.WriteLine( "Hello{0}World!", MyString );   
string TrimString = MyString.Trim();
Console.WriteLine( "Hello{0}World!", TrimString );
这段代码将以下两行显示到控制台。
Hello Big   World!
HelloBigWorld! 

TrimEnd

String.TrimEnd 方法从字符串的结尾移除字符,同时创建新的字符串对象。通过为此方法传递一个字符数组来指定要移除的字符。字符数组中的元素顺序并不影响剪裁操作。当找到未在数组中指定的字符时,剪裁停止。

下面的示例使用 TrimEnd 方法移除字符串最后面的字母。在此示例中,'r' 字符和 'W' 字符的位置反转,以阐释数组中字符的顺序并不重要。请注意,此代码移除 MyString 的最后一个单词和第一个单词的一部分。

string MyString = "Hello World!";
char[] MyChar = {'r','o','W','l','d','!',' '};
string NewString = MyString.TrimEnd(MyChar);
Console.WriteLine(NewString);

此代码将 He 显示到控制台。

下面的示例使用 TrimEnd 方法移除字符串的最后一个单词。在此代码中,单词 Hello 后尾随一个逗号,而由于在要剪除的字符的数组中没有指定逗号,因此剪裁在逗号处结束。

string MyString = "Hello, World!";
char[] MyChar = {'r','o','W','l','d','!',' '};
string NewString = MyString.TrimEnd(MyChar);
Console.WriteLine(NewString);

此代码将 Hello, 显示到控制台。

TrimStart

String.TrimStart 方法类似于 String.TrimEnd 方法,不同之处在于它通过从现有字符串对象的开头移除字符来创建新的字符串。通过向 TrimStart 方法传递一个字符数组来指定要移除的字符。使用 TrimEnd 方法时,字符数组中元素的顺序并不影响剪裁操作。当找到未在数组中指定的字符时,剪裁停止。

下面的示例移除字符串的第一个单词。在此示例中,'l' 字符和 'H' 字符的位置反转,以阐释数组中字符的顺序并不重要。

string MyString = "Hello World!";
char[] MyChar = {'e', 'H','l','o',' ' };
string NewString = MyString.TrimStart(MyChar);
Console.WriteLine(NewString);

此代码将 World! 显示到控制台。
Remove

String.Remove 方法,从现有字符串的指定位置开始,移除指定数量的字符。此方法采用从零开始的索引。

下面的示例从字符串的从零开始的索引的第五个位置开始,从该字符串中移除十个字符。

string MyString = "Hello Beautiful World!";  
Console.WriteLine(MyString.Remove(5,10));

此代码将 Hello World! 显示到控制台。

转载于:https://www.cnblogs.com/symbol441/archive/2007/12/28/1018176.html

#define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #include <windows.h> #include <stdint.h> #pragma comment(lib, "ws2_32.lib") #define BUFFER_SIZE 4096 #define PORT 40000 int main() { WSADATA wsa; SOCKET sock, client_sock; struct sockaddr_in server, client; printf("Initializing Winsock...\n"); if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("WSAStartup failed. Error: %d\n", WSAGetLastError()); return 1; } printf("Creating socket...\n"); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { printf("Socket creation failed. Error: %d\n", WSAGetLastError()); return 1; } server.sin_addr.s_addr = INADDR_ANY; // 监听所有IP server.sin_family = AF_INET; server.sin_port = htons(PORT); printf("Binding socket...\n"); if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { printf("Bind failed. Error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return 1; } printf("Listening for connections...\n"); listen(sock, 10); int addr_len = sizeof(client); if ((client_sock = accept(sock, (struct sockaddr*)&client, &addr_len)) == INVALID_SOCKET) { printf("Accept failed. Error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return 1; } printf("Client connected: %s:%d. Enter commands (q to quit):\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); while (1) { char choice[2]; printf("a.文件下载\nb.命令控制\nc.推出\n"); printf("input choice:"); fgets(choice, sizeof(choice), stdin); send(client_sock, choice, 1, 0); // 清空输入缓冲区 int c; while ((c = getchar()) != '\n' && c != EOF); send(client_sock, choice, 1, 0); if (choice[0] == 'c') { break; } if (choice[0] == 'a') { while (1) { //先输入下载文件名 char downfilename[100] = { 0 }; printf("Input filename to download: "); gets_s(downfilename); if (strcmp(downfilename, "q") == 0) { send(client_sock, "q", 1, 0); break; } send(client_sock, downfilename, strlen(downfilename), 0); //再输入保存文件名,看文件是否能创建成功 char savefilename[100] = { 0 }; //文件名 printf("Input filename to save: "); gets_s(savefilename); FILE* fp = fopen((const char*)savefilename, "wb"); //以二进制方式打开(创建)文件 if (fp == NULL) { printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } //循环接收数据,直到文件传输完毕 char buffer[BUFFER_SIZE] = { 0 }; //文件缓冲区 int nCount; while ((nCount = recv(client_sock, buffer, BUFFER_SIZE, 0)) > 0) { fwrite(buffer, nCount, 1, fp); } puts("File transfer success!"); //文件接收完毕后直接关闭套接字,无需调用shutdown() fclose(fp); } } if (choice[0] == 'b') { while (1) { char cmd[BUFFER_SIZE]; printf("Enter command: "); fgets(cmd, BUFFER_SIZE, stdin); cmd[strcspn(cmd, "\n")] = '\0'; // 去除换行 if (strcmp(cmd, "q") == 0) { send(client_sock, "q", 1, 0); break; } send(client_sock, cmd, strlen(cmd), 0); // 接收数据长度 uint32_t len; recv(client_sock, (char*)&len, sizeof(len), 0); // 接收数据 char* result = (char*)malloc(len + 1); recv(client_sock, result, len, 0); result[len] = '\0'; printf("Result:\n%s\n", result); free(result); } } } closesocket(client_sock); closesocket(sock); WSACleanup(); return 0; } 服务器端程序是这样的,是否是服务器端程序的问题
最新发布
08-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值