这个我的聊天与线程混合在一起运行服务器和聊天。问题是,当我向聊天发送消息时,让“Hello”作为第一条消息, 和“再见”作为第二个 输出将: 你好 Byelo和一些我不想要的额外角色 如何删除聊天的额外字符和字母? C ++ 我试过cout<<“消息:”<
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <iostream>
#include <cpl.h>
#include <string>
using namespace std;
DWORD WINAPI Thread(LPVOID);
HANDLE Thread_Handle = NULL;
DWORD Thread_ID = 0;
DWORD WINAPI Thread(LPVOID data)
{
while(1){
WSADATA t_wsa; // WSADATA structure
WORD wVers; // version number
int iError; // error number
wVers = MAKEWORD(2, 2); // Set the version number to 2.2
iError = WSAStartup(wVers, &t_wsa); // Start the WSADATA
if(iError != NO_ERROR || iError == 1){
// MessageBox(NULL, (LPCTSTR)"Error at WSAStartup()", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
WSACleanup();
}
if(LOBYTE(t_wsa.wVersion) != 2 || HIBYTE(t_wsa.wVersion) != 2){
// MessageBox(NULL, (LPCTSTR)"Error at WSAStartup()", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
WSACleanup();
}
SOCKET sServer;
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sServer == INVALID_SOCKET || iError == 1){
// MessageBox(NULL, (LPCTSTR)"Invalid Socket!", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
WSACleanup();
}
SOCKADDR_IN sinServer;
memset(&sinServer, 0, sizeof(sinServer));
sinServer.sin_family = AF_INET;
sinServer.sin_addr.s_addr = INADDR_ANY; // Where to start server?
sinServer.sin_port = htons( 1002); // Port
if(bind(sServer, (LPSOCKADDR)&sinServer, sizeof(sinServer)) == SOCKET_ERROR){
/* failed at starting server */
// MessageBox(NULL, (LPCTSTR)"Could not bind the server!", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
WSACleanup();
}
while(listen(sServer, 20) == SOCKET_ERROR){
Sleep(10);
}
SOCKET sClient;
int szlength;
szlength = sizeof(sinServer);
sClient = accept(sServer, (LPSOCKADDR)&sinServer, &szlength);
if (sClient == INVALID_SOCKET){
// MessageBox(NULL, (LPCTSTR)"Could not accept this client!", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
closesocket(sServer);
WSACleanup();
} else {
// MessageBox(NULL, (LPCTSTR)"Accepted a Client!", (LPCTSTR)"Server::Success", MB_OK);
}
// Now we can send/recv data!
int iRet;
char buffer[200];
// strcpy(buffer, "Welcome to our Server!\0");
iRet = send(sClient, buffer, strlen(buffer), 0);
if(iRet == SOCKET_ERROR){
//MessageBox(NULL, (LPCTSTR)"Could not send data!", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
closesocket(sClient);
closesocket(sServer);
WSACleanup();
}
char autoresponse[80];
int bytes;
// strcpy(autoresponse, "Message Received!");
autoresponse[strlen(autoresponse)-1] = 0;
//MessageBox(NULL, (LPCTSTR)"Server is ready for messages and is hiding!", (LPCTSTR)"Server::Success", MB_OK);
char *cClientMessage;
cClientMessage = new char[600];
cClientMessage[599] = 0;
while(bytes = recv(sClient, cClientMessage, 599, 0)){
if(bytes < 1){
continue;
}
char cRead[99];///////////////////////////////////////////////////////////////////
cout<<"Message: "<<cClientMessage<<" \n";
/////////////////////////////////////////////////////////////////////////////
iRet = send(sClient, autoresponse, strlen(autoresponse), 0);
if(iRet == SOCKET_ERROR){
// MessageBox(NULL, (LPCTSTR)"Could not send response!", (LPCTSTR)"Server::Error", MB_OK|MB_ICONERROR);
}}
delete [] cClientMessage;
// Cleanup
closesocket(sClient);
closesocket(sServer);
// Shutdown Winsock
WSACleanup();
Sleep(10);
}
return (0);
}
int main()
{
Thread_Handle = CreateThread(NULL,0,Thread,(LPVOID)0,0,&Thread_ID);
while(1){
char IP[100];
char message[255];
cout<<"IP: \n";
cin>>IP;
char buffer[150];
WSADATA t_wsa; // WSADATA structure
WORD wVers; // version number
int iError; // error number
wVers = MAKEWORD(2, 2); // Set the version number to 2.2
iError = WSAStartup(wVers, &t_wsa); // Start the WSADATA
if(iError != NO_ERROR || iError == 1){
MessageBox(NULL, (LPCTSTR)"Error at WSAStartup()", (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
WSACleanup();
return 0;
}
/* Correct version? */
if(LOBYTE(t_wsa.wVersion) != 2 || HIBYTE(t_wsa.wVersion) != 2){
MessageBox(NULL, (LPCTSTR)"Error at WSAStartup()", (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
WSACleanup();
return 0;
}
SOCKET sClient;
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sClient == INVALID_SOCKET || iError == 1){
MessageBox(NULL, (LPCTSTR)"Invalid Socket!", (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
WSACleanup();
return 0;
}
SOCKADDR_IN sinClient;
memset(&sinClient, 0, sizeof(sinClient));
char cIP[50];
sinClient.sin_family = AF_INET;
sinClient.sin_addr.s_addr = inet_addr(IP); // Where to start server?
sinClient.sin_port = htons(1003); // Port
if(connect(sClient, (LPSOCKADDR)&sinClient, sizeof(sinClient)) == SOCKET_ERROR){
/* failed at starting server */
MessageBox(NULL, (LPCTSTR)"Could not connect to the server!", (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
WSACleanup();
return 0;
}
while(1){
cout<<"Message: \n";
cin.getline(message,255);
string input2 = message;
// Now we can send/recv data!
int iRet;
char cBuffer[600];
char buffer2[260];
// MessageBox(NULL, (LPCTSTR)"Connected!", (LPCTSTR)"Client::Server", MB_OK|MB_ICONEXCLAMATION);
strcpy(buffer, message );
iRet = send(sClient, buffer, strlen(buffer), 0); //send data
if(iRet == SOCKET_ERROR){
MessageBox(NULL, (LPCTSTR)"Could not send data!", (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
WSACleanup();
return 0;
}
}
int bytes;
bytes = SOCKET_ERROR;
char *cServerMessage;
cServerMessage = new char[600];
while(bytes = recv(sClient, cServerMessage, 599, 0)){
if(bytes == SOCKET_ERROR){
char cError[500];
sprintf(cError, "Connection failed, WINSOCK error code: %d", WSAGetLastError());
MessageBox(NULL, (LPCTSTR)cError, (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
closesocket(sClient);
// Shutdown Winsock
WSACleanup();
return 0;
}
if (bytes == 0 || bytes == WSAECONNRESET) {
MessageBox(NULL, (LPCTSTR)"Connection Disconnected!", (LPCTSTR)"Client::Error", MB_OK|MB_ICONERROR);
closesocket(sClient);
// Shutdown Winsock
WSACleanup();
return 0;
}
if(bytes < 1){
Sleep(300);
continue;
}
delete [] cServerMessage;
// Cleanup
closesocket(sClient);
// Shutdown Winsock
WSACleanup();
return 0;
}
Sleep(10);
// This is how to terminate a thread // TerminateThread(Thread_Handle,0);
}
return 0;
}
答案 0 :(得分:1)
recv()
不会在写入的字节末尾追加'\0'
。您需要使用recv()
的返回值并自行添加'\0'
。
答案 1 :(得分:0)
如果您不关心带宽的额外字节,最快的修复可能只是在调用send()时发送strlen(缓冲区)+1字节的strlen(缓冲区)字节。
答案 2 :(得分:0)
为什么不将前4个字节放在消息的长度上?
答案 3 :(得分:0)
为了保持简单(我不认为这里有性能或风格),你应该在函数Thread中设置整个cClientMessage(例如memset(cClientMessage,0,600))。然后也从发件人那里用主要的消息做同样的事。
由于接收器未传输或设置\ 0,因此您从上一条消息中获取过时的字符。