【发布时间】:2015-12-27 22:17:20
【问题描述】:
我在服务器和客户端之间使用套接字发送和接收字符串时遇到了一点问题。在此代码中,首先服务器将“已建立连接(意大利语为“connessione avvenuta”)发送到客户端(将其打印在屏幕上),然后客户端扫描一个字符串并将其发送到服务器,服务器删除元音并将其发送再次给客户。 当我用客户端打印它时,奇怪的字符出现在字符串的末尾,我想是因为我没有很好地关闭它。如何做到这一点?
**SERVER SIDE**
#if defined WIN32
#include <winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 30
void ClearWinSock() {
#if defined WIN32
WSACleanup();
#endif
}
int main(void) {
//---------------------------INIZIALIZZAZIONE WSADATA
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf ("Error at WSAStartup");
return 0;
}
#endif
//-------------------------------CREAZIONE SOCKET
int Mysocket;
Mysocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Mysocket < 0) {
printf("socket creation failed\n");
return 0;
}
struct sockaddr_in sad;
memset(&sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr ("127.0.0.1");
sad.sin_port = htons (9888);
//------------------------ASSEGNAZIONE PORTA E IP ALLA SOCKET
if (bind(Mysocket, (struct sockaddr*) &sad, sizeof(sad)) <0) {
printf ("bind() failed\n");
closesocket(Mysocket);
return 0;
}
//---------------------------SETTAGGIO SOCKET ALL'ASCOLTO
int qlen = 10;
if (listen (Mysocket, qlen) < 0) {
printf("listen() failed\n");
closesocket(Mysocket);
return 0;
}
struct sockaddr_in cad;
int Csocket;
int clientlen;
//------------------------------ACCETTA LA CONNESSIONE
while (1) {
printf("In attesa di un client con cui comunicare\n");
memset(&cad, 0, sizeof(cad));
clientlen = sizeof(cad);
if((Csocket = accept(Mysocket, (struct sockaddr*) &cad, &clientlen)) < 0) {
printf ("accept failed\n");
closesocket(Mysocket);
ClearWinSock();
return 0;
}
printf("connesso con il client\n");
//---------------------------------------INVIO STRINGA AL CLIENT
char* inputString = "connessione avvenuta";
int stringlen = strlen(inputString);
if (send(Csocket, inputString, stringlen, 0) != stringlen) {
printf("client-send() sent a different number of bytes than expected");
closesocket(Csocket);
ClearWinSock();
system ("pause");
return 0;
}
//-------------------------------------RICEZIONE STRINGA DAL CLIENT
char str1[BUFSIZE+1]; char str1des[BUFSIZE+1];
int i,j=0;
//recv (Csocket, str1, BUFSIZE - 1, 0);
int read = recv(Csocket, str1, BUFSIZE-1, 0); str1[read] = '\0';
//-------------------------------ELIMINAZIONE VOCALI DALLA STRINGA RICEVUTA
for(i=0;i<=strlen(str1)+1;i++) {
if(str1[i]=='a'||str1[i]=='e'||str1[i]=='i'||str1[i]=='o'||str1[i]=='u' ||str1[i]=='A'||str1[i]=='E'||str1[i]=='I'||str1[i]=='O'||str1[i]=='U')
str1[i]=' ';
else
str1des[j++]=str1[i];
}
str1des[j]='\0';
//-----------------------------------INVIO STRINGA ELABORATA AL CLIENT
if (send(Csocket, str1des, strlen(str1des), 0) != strlen(str1des)) {
printf("client-send() sent a different number of bytes than expected");
closesocket(Csocket);
ClearWinSock();
system ("pause");
return 0;
}
}
//------------------------------------------CHIUSURA CONNESSIONE
closesocket (Csocket);
ClearWinSock();
printf ("\n");
system ("pause");
return 0;
}
**CLIENT SIDE**
#if defined WIN32
#include <winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 30
void ClearWinSock() {
#if defined WIN32
WSACleanup();
#endif
}
//-----------------------------INIZIALIZZAZIONE WSADATA
int main (void) {
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup (MAKEWORD (2,2), &wsaData);
if (iResult !=0) {
printf ("error at WSASturtup\n");
return 0;
}
#endif
//--------------------------------CREAZIONE SOCKET
int Csocket;
Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Csocket < 0) {
printf ("socket creation failed");
closesocket (Csocket);
ClearWinSock();
return 0;
}
//--------------------------COSTRUZIONE INDIRIZZO SERVER
struct sockaddr_in sad;
memset (&sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr ("127.0.0.1");
sad.sin_port = htons (9888);
//------------------------------CONNESSIONE AL SERVER
if (connect(Csocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
printf ("failed to connect\n");
closesocket (Csocket);
ClearWinSock();
return 0;
}
//-----------------------------RICEZIONE DATI DAL SERVER
char buf[BUFSIZE+1];
int read = recv (Csocket, buf, BUFSIZE - 1, 0);
if (read <=0) {
printf ("Qualcosa non và!\n");
}
else {
buf[read+1] = '\0';
printf("Server scrive: %s\n", buf);
}
//----------------------------INVIO PRIMA STRINGA AL SERVER
char str1[BUFSIZE+1]; int stringlen = strlen(str1);
printf ("inserisci prima stringa:\n");
scanf ("%s", str1);
if (send(Csocket, str1, stringlen, 0) != stringlen) {
printf("client-send() sent a different number of bytes than expected");
closesocket(Csocket);
ClearWinSock();
system ("pause");
return 0;
}
//------------------------------RICEZIONE STRINGA ELABORATA DAL SERVER
char buf2[BUFSIZE+1];
int read2 = recv (Csocket, buf2, BUFSIZE - 1, 0);
if (read2 <=0) {
printf ("Qualcosa non và!\n");
}
else {
buf2[read+1] = 0;
printf("Server scrive: %s\n", buf2);
}
//---------------------------------------CHIUSURA CONNESSIONE
closesocket (Csocket);
ClearWinSock();
printf ("\n");
system ("pause");
return 0;
}
【问题讨论】:
-
您没有为您的字符串发送终止
NUL字符。也就是说,传递给服务器上所有send调用的len参数必须是stringlen+1。 -
另外,在客户端上,您正在设置
int stringlen = sizeof(str1)并将其用作len参数到send。虽然这不会导致您描述的问题,但它确实发送了不必要的数据,因为sizeof(str1)是整个缓冲区,包括实际字符串结束后的垃圾。 -
另一个问题是您假设每个
recv将从单个send中获取所有数据。这不是recv的工作方式。它可以返回少于整个发送消息。所以recv几乎总是在一个循环中调用,它检查是否收到了整个消息。来自recvman page:“接收调用通常会返回任何可用的数据,直到请求的数量,而不是等待收到请求的全部数量。” -
服务器代码:char str1[BUFSIZE]; recv(Csocket, str1, BUFSIZE-1, 0); for (i=0; i
-
@cm161 添加:int read = recv(Csocket, str1, BUFSIZE-1, 0); str1[read] = '\0' --- str1[BUFSIZE]='\0' 已删除 --- stringlen = strlen(str1) 已修复(删除 sizeof)。我需要在 send() 上解决什么问题?因为还是不行..