这是一个简单的代码tcp客户端/服务器,服务器在建立连接后发送“Hello from Server”。我的问题是:
1)客户端在关闭server.exe窗口后写入字符串并且不知道原因;
2)客户端打印奇怪的字符而不是“来自服务器的Hello”。我错过了输出格式的东西。
SERVER
#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>
#define PROTOPORT 5193 //default protocol port number
#define QLEN 6 // size of request queue
#define BUFFERSIZE 10
void ErrorHandler (char *errorMessage) {
printf (errorMessage);
}
void ClearWinSock() {
#if defined WIN32
WSACleanup ();
#endif
}
int main(void) {
#if defined WIN32
WSADATA wsaData;
int iResult = WSAStartup (MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
ErrorHandler ("Error at WSAStartup()\n");
return 0;
}
#endif
// CREAZIONE DELLA SOCKET
int MySocket;
MySocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MySocket < 0) {
ErrorHandler ("socket creation failed.\n");
ClearWinSock();
return 0;
}
// ASSEGNAZIONE DI UN INDIRIZZO ALLA SOCKET
struct sockaddr_in sad;
memset (&sad, 0, sizeof (sad)); //ensures that extra bytes contain 0
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = inet_addr ("127.0.0.1"); //ip del server con conversione
//da notazione dotted-decimal in un numero a 32 bit
//espresso nella rappresentazione della rete
sad.sin_port = htons (5193); //host to network short
//Assegnazione porta e ip alla socket e verifica presenza di eventuali errori
if (bind (MySocket, (struct sockaddr*) & sad, sizeof (sad)) < 0) {
ErrorHandler ("bind() failed.\n");
closesocket (MySocket);
ClearWinSock ();
return 0;
}
// SETTAGGIO DELLA SOCKET ALL'ASCOLTO
if (listen (MySocket, QLEN) < 0) {
ErrorHandler ("listen() failed.\n");
closesocket (MySocket);
ClearWinSock ();
return 0;
}
// ACCETTARE UNA NUOVA CONNESSIONE - e creazione di una nuova socket per comunicare con il client
struct sockaddr_in cad; //structure for the client address
int clientSocket; // socket descriptor for the client
int clientLen; //the size of the client address
printf ("Waiting for a client to connect...");
while (1) {
clientLen = sizeof (cad); //set the size of the client address
if ((clientSocket = accept (MySocket, (struct sockaddr*) &cad, &clientLen)) < 0) {
ErrorHandler ("accept() failed.\n");
// CHIUSURA DELLA CONNESSIONE
closesocket (MySocket);
ClearWinSock ();
return 0;
}
printf ("Handling client %s\n", inet_ntoa (cad.sin_addr));
}
char* inputString = "Hello from server"; // Stringa da inviare
int stringLen = strlen (inputString); // Determina la lunghezza
// INVIARE DATI AL CLIENT
if (send (clientSocket, inputString, stringLen, 0) != stringLen) {
ErrorHandler ("send () sent a different number of bytes than expected");
closesocket (clientSocket);
ClearWinSock();
system("pause");
return 0;
}
closesocket(MySocket);
ClearWinSock ();
return 0;
}
客户端
#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>
#define BUFFERSIZE 20 // Dimensione buffer che riceve dati dal server
#define PROTOPORT 5193 // Numero di porta di default
void ErrorHandler (char *errorMessage) {
printf (errorMessage);
}
void ClearWinSock () {
#if defined WIN32
WSACleanup();
#endif
}
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 DELLA SOCKET
int Csocket;
Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Csocket < 0) {
ErrorHandler ("socket creation failed.\n");
closesocket (Csocket);
ClearWinSock ();
return 0;
}
// COSTRUZIONE DELL'INDIRIZZO DEL 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"); //ip del server con conversione
//da notazione dotted-decimal in un numero a 32 bit
//espresso nella rappresentazione della rete
sad.sin_port = htons (5193); // Server port
//CONNESSIONE AL SERVER
if (connect (Csocket, (struct sockaddr*) &sad, sizeof (sad)) < 0) {
ErrorHandler ("Failed to connect.\n");
closesocket (Csocket);
ClearWinSock();
return 0;
}
char buf[BUFFERSIZE];
recv (Csocket, buf, BUFFERSIZE - 1, 0);
printf("Server scrive: %s\n",buf);
// CHIUSURA DELLA CONNESSIONE
closesocket (Csocket);
ClearWinSock();
printf ("\n");
system ("pause");
return 0;
}
最后:如果我要发送更多字符串,我是否要为每个字符串使用一个send()和一个recv()?
答案 0 :(得分:1)
最大的问题是你没有突破服务器循环。这就是为什么在退出服务器之前,您在客户端上看不到任何内容的原因。程序终止时套接字关闭,因此客户端中的recv
调用不再阻塞。此外,在客户端,您不会检查recv
的返回值并打印垃圾邮件。
服务器修复:
while (1) {
clientLen = sizeof (cad); //set the size of the client address
if ((clientSocket = accept (MySocket, (struct sockaddr*) &cad, &clientLen)) < 0) {
....
}
printf ("Handling client %s\n", inet_ntoa (cad.sin_addr));
break; // <- terminate loop,
// or just get rid of the loop altogether as there
// is no real need for it I can see
}
客户端修复:
int read = recv (Csocket, buf, BUFFERSIZE - 1, 0);
if (read <= 0) {
// Not successful
}
else {
buf[read] = 0; // Add eos
printf("%s", buf);
}