I try to make a application that client send a message and the server respond on the same machine using winsock TCP c++. The problem is that after the server waited for client to connect, I ran the client code and it stopped at the connect and exit. This is my code.
Server:
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iostream>
#define MY_PORT 8888
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//Init Winsock
WSADATA SData;
if (WSAStartup(0x0202, &SData) != 0)
{
cout << "KHONG THE KHOI DONG WINSOCK";
return 1;
}
//Init Socket
int listeningSocket;
if ((listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
perror("socket failed");
WSACleanup();
exit(EXIT_FAILURE);
}
//Set IP and PORT
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MY_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//Bind
if (bind(listeningSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("bind failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
//Listen
if (listen(listeningSocket, 5) < 0)
{
perror("listen failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
//Accept
int new_socket;
sockaddr_in client_addr;
int nSizeAddr = sizeof(sockaddr);
if (new_socket = accept(listeningSocket, (struct sockaddr *)&client_addr, &nSizeAddr) < 0)
{
perror("accept failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
while (1)
{
//recv
char buff[100];
if (recv(new_socket, buff, 100, 0) < 0)
{
perror("recv failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
cout << buff << endl;
//send
string sndStr = "Da nhan";
if (send(new_socket, sndStr.c_str(), sndStr.size(), 0) < 0)
{
perror("send failed");
closesocket(listeningSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
}
//close socket
closesocket(new_socket);
//Cleanup winsock
WSACleanup();
return 0;
}
Client:
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iostream>
#include <string>
#define MY_PORT 8888
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//Init winsock
WSADATA SData;
if (WSAStartup(0x0202, &SData) != 0)
{
cout << "KHONG THE KHOI DONG WINSOCK";
return 1;
}
//Init socket
int clientSocket;
if (clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
{
perror("socket failed");
WSACleanup();
exit(EXIT_FAILURE);
}
//Set IP and PORT
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MY_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY; //Vi Client-Server chung 1 may
//Connect
if (connect(clientSocket, (SOCKADDR*)&server_addr, sizeof(server_addr)) < 0)
{
perror("connect failed");
closesocket(clientSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
while (1)
{
//Send
string sndStr;
getline(cin, sndStr);
if (send(clientSocket, sndStr.c_str(), sndStr.size(), 0) < 0)
{
perror("send failed");
closesocket(clientSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
//Recv
char buff[100];
if (recv(clientSocket, buff, 100, 0) < 0)
{
perror("recv failed");
closesocket(clientSocket);
WSACleanup();
exit(EXIT_FAILURE);
}
cout << buff << endl;
}
//Close socket
closesocket(clientSocket);
//Cleanup Winsock
WSACleanup();
}
It had an error at the accept step but I don't know what was the error name. How can I fix it?
The client_socket value turn out INVALID_SOCKET.
EDIT: New problem found - I still don't believe that using INADDR_ANY as a client address is good, but that isn't actually the problem here.
Instead the problem is in the line:
if (clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
Note that < has higher precedence than =, so you assign a boolean value to clientSocket here. The similar line in the server code has parenthesis added that makes it work correctly.
Working line in the server code:
if ((listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
OLD ANSWER: I still stand by this, but it isn't the problem here
.
This is your problem right here (in the client):
server_addr.sin_addr.s_addr = INADDR_ANY; //Vi Client-Server chung 1 may
The way sockets work, is that you create a server socket that listens for incoming connections, and on creation you tell it who to accept connections from. Either from a specific address, a range of addresses, or just from anybody. The third option is the most common one here, and the one you have chosen in your server (bind to address INADDR_ANY).
This part is good.
However, when the client has to connect to the server, you cannot just say: "Connect to whatever!" and expect it to find your server (or anything at all). So when you try to connect with the client socket you have to give it the actual address of the server.
I found a example of how to do this:
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr*) & serv_addr, sizeof(serv_addr)) < 0)
Change the address to the correct one for your server, if localhost (127.0.0.1) don't work for you.
Related
I am currently experiencing some trouble while testing UDP sockets.
So I have 2 c programs, one sends and receives, the other receives and sends a message.
Here is send_recv.c:
#define PORT 1010
int main(int argc, const char *argv[]) {
int socketInfo, opt;
struct sockaddr_in server;
char msgOut[30], msgIn[30];
opt = 1;
printf("Input message: ");
fgets(msgOut, 30, stdin);
socketInfo = socket(AF_INET, SOCK_DGRAM, 0);
if(socketInfo < 0) {
perror("socket error");
return EXIT_FAILURE;
}
if(setsockopt(socketInfo, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt failed");
return EXIT_FAILURE;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
if(bind(socketInfo, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("bind error");
return EXIT_FAILURE;
}
if(connect(socketInfo, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("connection error");
return EXIT_FAILURE;
}
puts("connected");
send(socketInfo, msgOut, strlen(msgOut), 0);
puts("sleeping for 5");
sleep(5);
puts("message sent");
recv(socketInfo, msgIn, sizeof(msgIn), 0);
printf("received msg: %s\n", msgIn);
close(socketInfo);
return EXIT_SUCCESS;
}
And here is recv_send.c:
#define PORT 1010
int main(int argc, const char *argv[]) {
int socketInfo, opt;
struct sockaddr_in server;
char msgOut[30], msgIn[30];
opt = 1;
socketInfo = socket(AF_INET, SOCK_DGRAM, 0);
if(socketInfo < 0) {
perror("socket error");
return EXIT_FAILURE;
}
if(setsockopt(socketInfo, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt failed");
return EXIT_FAILURE;
}
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
if(bind(socketInfo, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("bind error");
return EXIT_FAILURE;
}
if(connect(socketInfo, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("connection error");
return EXIT_FAILURE;
}
puts("connected");
recv(socketInfo, msgIn, sizeof(msgIn), 0);
printf("received msg: %s\n", msgIn);
printf("Input message: ");
fgets(msgOut, 30, stdin);
send(socketInfo, msgOut, strlen(msgOut), 0);
puts("message sent");
close(socketInfo);
return EXIT_SUCCESS;
}
The problem is that the receive program never receives anything, and the send program sends and then just receives the message it already received.
The output of send_rcv is this:
Input message: hello there
connected
message sent
received msg: hello there
and the output of rcv_send is this:
connected
(ctrl+z) Job 6, 'sudo ./rcv_send' has stopped
Another problem is that when I don't run the program with sudo it just says this: bind error: Permission denied
The problem is that both endpoints are listening on the same port while running on the same machine, and you have both sides sending to INADDR_ANY.
Also, port numbers below 1024 are privileged ports and therefore require root access to bind to.
Use a different port (1024 or higher) for each side of the connection, and choose a specific IP address to connect to. For example:
#define LOCAL_PORT 1100
#define REMOTE_PORT 1101
...
struct sockaddr_in local, remote;
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(LOCAL_PORT);
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
remote.sin_port = htons(LOCAL_PORT);
if(bind(socketInfo, (struct sockaddr *)&local, sizeof(local)) < 0) {
perror("bind error");
return EXIT_FAILURE;
}
if(connect(socketInfo, (struct sockaddr *)&remote, sizeof(remote)) < 0) {
perror("connection error");
return EXIT_FAILURE;
}
The values of LOCAL_PORT and REMOTE_PORT would be swapped in the two programs.
Note also that you can get rid of the setsockopt call as you don't have two programs open on the same port.
#define PORT 3000
int sock()
{
int valread;
struct sockaddr_in serv_addr;
const char* hello = "Hello from client";
char buffer[1024] = { 0 };
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
return 0;
}
I have this code for the sockets, to be sent at localhost:3000 address. But they are not sent, and Connection failed error pops up. I have node.js server listener socket open at that port.
On Windows only 1, you must call WSAStartup() to initialize the Winsock library before using any other socket functions, like connect(). See Initializing Winsock. And you should call WSACleanup() when you are done using Winsock.
1: On non-Windows platforms, there are no equivalent startup/cleanup functions that need to be called when using sockets.
Try something more like this:
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#define PORT 3000
int main()
{
WSADATA wsa;
int iResult = WSAStartup(MAKEWORD(2,0), &wsa);
if (iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return INVALID_SOCKET;
}
printf("Winsock initialized\n");
struct sockaddr_in serv_addr;
ZeroMemory(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("Invalid address/ Address not supported \n");
WSACleanup();
return -1;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("Socket creation failed: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR)
{
printf("Connection failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
printf("Connection successful\n");
const char* hello = "Hello from client";
if (send(sock, hello, strlen(hello), 0) == SOCKET_ERROR)
{
printf("Send failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
printf("Hello message sent\n");
closesocket(sock);
WSACleanup();
return 0;
}
That said, you really should be using getaddrinfo() instead of inet_pton(), especially if you want to support both IPv4 and IPv6, eg:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#define PORT "3000"
int main()
{
WSADATA wsa;
int iResult = WSAStartup(MAKEWORD(2,0), &wsa);
if (iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return INVALID_SOCKET;
}
printf("Winsock initialized\n");
struct addrinfo hints, *addrs;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Convert IPv4 and IPv6 addresses from text to binary form
iResult = getaddrinfo("127.0.0.1", PORT, &hints, &addrs);
if (iResult != 0)
{
printf("Get Address Info failed: (%d) %s\n", iResult, gai_strerror(iResult));
WSACleanup();
return -1;
}
SOCKET sock = INVALID_SOCKET;
for(struct addrinfo *addr = addrs; addr != NULL; addr = addr->ai_next)
{
sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sock != INVALID_SOCKET)
{
if (connect(sock, addr->ai_addr, addr->ai_addrlen) != SOCKET_ERROR)
break;
closesocket(sock);
sock = INVALID_SOCKET;
}
}
if (sock == INVALID_SOCKET)
{
printf("Socket creation failed/Connection failed\n");
WSACleanup();
return -1;
}
printf("Connection successful\n");
const char* hello = "Hello from client";
if (send(sock, hello, strlen(hello), 0) == SOCKET_ERROR)
{
printf("Send failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
printf("Hello message sent\n");
closesocket(sock);
WSACleanup();
return 0;
}
I am currently a student at Automatics and Applied Informatics. I have a project from Computer Networking, in which I need to make a chat application with the help of threads. Since now I made the receiving part of the connection for the server and made the client, but I get a debug assertion failed error when I run the program. Until now I only have the user connecting part. I really need some help with this because I am stuck.
tcp_server.cpp
#include "winsock2.h"
#include "ClientThread.h"
#include <stdio.h>
#include <string.h>
#include <vector>
#include "ws2tcpip.h"
#pragma comment(lib,"ws2_32.lib")
const unsigned int SysThread::INFINIT_WAIT = UINT_MAX;
void main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
printf("Error at WSAStartup()\n");
return;
}
// Socket for listening for incoming requests
SOCKET ListenSocket;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("Error at the listening socket, error code: %d\n", WSAGetLastError);
WSACleanup();
return;
}
int Port = 1300;
char IP[10] = "127.0.0.1";
sockaddr_in ServerAddress;
int ServerLen = sizeof(ServerAddress);
ServerAddress.sin_family = AF_INET;
ServerAddress.sin_port = htons(Port);
inet_pton(AF_INET, IP, &ServerAddress.sin_addr);
if (bind(ListenSocket, (SOCKADDR*)&ServerAddress, sizeof(ServerAddress)) == SOCKET_ERROR) {
printf("bind() failed.\n");
closesocket(ListenSocket);
WSACleanup();
return;
}
if (listen(ListenSocket, 1) == SOCKET_ERROR) {
printf("Error listening on socket.\n");
WSACleanup();
return;
}
std::vector <char*> username;
int RecUserLen = 100;
char RecUser[100];
int ReceiveTheUsername;
// Socket for accepting incoming requests
SOCKET AcceptSocket;
printf("Waiting for client to connect...\n");
while (AcceptSocket = accept(ListenSocket, NULL, NULL)) {
printf("Succesful connection.\n");
int UserNum = 1;
ReceiveTheUsername = recv(AcceptSocket, RecUser, RecUserLen-1, 0);
username[UserNum] = RecUser;
printf("Username: %s", username[UserNum]);
}
}
tcp_client.cpp
#include <iostream>
#include <stdio.h>
#include <string.h>
#include "winsock2.h"
#include "ws2tcpip.h"
#pragma comment(lib, "ws2_32.lib")
void main()
{
int iResult;
//----------------------
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
printf("Hiba a WSAStartup() –nál\n");
//----------------------
SOCKET ClientSocket;
ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ClientSocket == INVALID_SOCKET)
{
printf("Error at initializing the socket, error code: %ld\n",
WSAGetLastError());
WSACleanup();
return;
}
//---------------------
int Port = 1300;
char IP[10] = "127.0.0.1";
sockaddr_in ServerAddr;
int AddrLen = sizeof(ServerAddr);
ServerAddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &ServerAddr.sin_addr);
ServerAddr.sin_port = htons(Port);
//----------------------
if (connect(ClientSocket, (SOCKADDR*)&ServerAddr, AddrLen) == SOCKET_ERROR)
{
printf("Connect error, error code: %ld\n",
WSAGetLastError());
WSACleanup();
return;
}
else {
printf("Succesful connection.\n");
}
//----------------------
char UserName[100];
printf("Enter the username: ");
fgets(UserName, 100, stdin);
int SendUsername;
SendUsername = send(ClientSocket, Felhasznalonev, sizeof(Felhasznalonev),0);
if (SendUsername == SOCKET_ERROR) {
printf("Error at sending the username.\n");
closesocket(ClientSocket);
WSACleanup();
return;
}
closesocket(ClientSocket);
WSACleanup();
return;
}
Well there's a clear problem here
std::vector <char*> username;
...
int UserNum = 1;
...
username[UserNum] = RecUser;
username is a zero sized vector, so username[UserNum] is an out of bounds vector access.
Not really sure why you are using a vector at all, it's not adding anything to the code as it currently is. But if you do need to use one then make sure that it is big enough.
The reason for the debug assertion failed error is as John said, you did not set the size of vector <char*> username, so you cannot directly set the value in the vector through assignment.
But the reason why you output garbled characters is that the bytes you read exceed the number of bytes actually returned.
According to the document:
Return value
If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.
Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling
So the return value of the recv function (in the code is ReceiveTheUsername) is actually the number of bytes actually read, not RecUserLen-1, so you can use ReceiveTheUsername to determine the validity of the returned string length.
You only need to initialize the string to be empty like the following code, you can prevent garbled characters.(Of course, you can also manually add '\0' according to the number of characters returned, or intercept the corresponding string according to the character length.)
char RecUser[100] = "";
while (AcceptSocket = accept(ListenSocket, NULL, NULL)) {
printf("Succesful connection.\n");
ReceiveTheUsername = recv(AcceptSocket, RecUser, RecUserLen - 1, 0);
username.push_back(RecUser);
printf("Username: %s", username.back());
}
I've been doing the Winsock tutorials and following it exactly. I can't seem to get either send() or recv() to function properly. I have a basic Server and Client program set up, and the connection is being made, but the Server isn't sending a message to the Client. Using the Telnet client also doesn't receive a response from the server. I'm not really sure what's happening, and all the questions I looked at were not basic or had stuff I couldn't really understand what they were doing.
Server.cpp
#include<WinSock2.h>
#include <io.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib") //winsock library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
sockaddr_in server, client;
int c;
char *message;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
else
printf("Initialised.\n");
//create a socket
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
return 2;
}
else
printf("Socket created.\n");
//prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.S_un.S_addr = INADDR_ANY;
server.sin_port = htons(8888);
//bind the socket
if (bind(s, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : &d", WSAGetLastError());
return 3;
}
else
puts("Bind done");
//listen
listen(s, 3);
//accept an incoming connection
puts("Waiting for incoming connections...");
c = sizeof(sockaddr_in);
while (new_socket = accept(s, (sockaddr *)&client, &c) != INVALID_SOCKET)
{
printf("Connect successful...\n");
//reply to the client
message = "Hello Client, I have recieved your connection, but I have to go now, bye!\n";
send(new_socket, message, strlen(message), 0);
puts("Message sent.\n");
}
if (new_socket == INVALID_SOCKET)
{
printf("accept() failed with error code : %d", WSAGetLastError());
return 4;
}
//close the socket
closesocket(s);
WSACleanup();
return 0;
}
Client.cpp
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <IPHlpApi.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main(int argc, char *argv[])
{
//intialize variables
WSADATA wsa;
char ip[100] = "192.168.1.117";
SOCKET s;
sockaddr_in server;
char *message, server_reply[75];
int recv_size;
//initialize Winsock
printf("\nInitialising Winsock...\n");
if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//create the socket
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
return 3;
}
printf("Socket created.\n");
server.sin_addr.S_un.S_addr = inet_addr(ip);
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//connect to the server
if (connect(s, (sockaddr *)&server, sizeof(server)) < 0)
{
puts("connect error");
return 4;
}
else
{
printf("Connect successful");
recv_size = recv(s, server_reply, 75, 0);
}
if (recv_size <= 0)
{
puts("recv() failed\n");
}
else
{
//add a NULL terminating character to make it a proper string before printing
server_reply[recv_size] = '\0';
puts(server_reply);
}
getchar();
//close the socket
closesocket(s);
WSACleanup();
return 0;
}
The client also fails to print the "recv() failed" line; it's like it's stuck at the recv() call.
On the server side:
you are not checking the return value of listen() for error.
you are not resetting c on each call to accept(), and you are not calling closesocket() on each client that is accepted.
you are not checking the return value of send() for error.
Try this instead:
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib") //winsock library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
sockaddr_in server, client;
int c, res, messagelen;
const char *message;
printf("\nInitializing Winsock...");
res = WSAStartup(MAKEWORD(2,2), &wsa);
if (res != 0)
{
printf("Failed. Error: %d\n", res);
return 1;
}
printf("Initialized.\n");
//create a socket
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket. Error: %d\n", WSAGetLastError());
return 2;
}
printf("Socket created.\n");
//prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.S_un.S_addr = INADDR_ANY;
server.sin_port = htons(8888);
//bind the socket
if (bind(s, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed. Error: &d", WSAGetLastError());
return 3;
}
printf("Bind done.\n");
//listen
if (listen(s, 3) == SOCKET_ERROR)
{
printf("Listen failed. Error: &d", WSAGetLastError());
return 4;
}
printf("Listening.\n");
//accept incoming connections
printf("Waiting for incoming connections...\n");
do
{
c = sizeof(sockaddr_in);
new_socket = accept(s, (sockaddr *)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("Failed to accept a client. Error: %d\n", WSAGetLastError());
return 5;
}
printf("Client connected...\n");
//reply to the client
message = "Hello Client, I have received your connection, but I have to go now, bye!\n";
messagelen = strlen(message);
do
{
res = send(new_socket, message, messagelen, 0);
if (res == SOCKET_ERROR)
{
printf("Failed to send message. Error: %d\n", WSAGetLastError());
break;
}
message += res;
messagelen -= res;
}
while (messagelen > 0);
if (messagelen == 0)
printf("Message sent.\n");
//close the client socket
closesocket(new_socket);
}
while (true);
//close the server socket
closesocket(s);
WSACleanup();
return 0;
}
On the client side, the only real problem I see is your recv() call has a potential buffer overflow waiting to happen, since you ask it to read 75 bytes, and that is the exact size of your buffer. It just happens that your server is only sending 74 bytes max, but if it ever sent more, you could overflow the buffer when appending the '\0' terminator to it.
So, either:
call recv() with sizeof(server_reply)-1 as the buffer size, to give yourself room for the added terminator:
recv_size = recv(s, server_reply, sizeof(server_reply)-1, 0);
use printf() instead of puts() so you don't need to null-terminate the buffer at all when printing it to the console. You can pass recv_size as a parameter to limit the amount of text being printed:
//server_reply[recv_size] = '\0';
//puts(server_reply);
printf("%.*s", recv_size, server_reply);
From the MSDN documentation on closesocket():
Note To assure that all data is sent and received on a connection, an application should call shutdown before calling closesocket (see Graceful shutdown, linger options, and socket closure for more information). Also note, an FD_CLOSE network event is not posted after closesocket is called.
Basically the data you have sent was still pending when you closed the socket.
I am running a server client winsock software to transmit data in a loop from client to server. There is no problem in first transmission and it is perfect.
The second transmission and so on is corrupted and I don't know if it is about keep alive or something else. I spent 2 days trying to figure out.
Server side
#include"stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include<Windows.h>
#include <time.h>
#include"iostream"
#include"string"
#define MAXLINE 1000
int main()
{
// Initialize Winsock
WSADATA wsaData;
std::string message;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
printf("Server: Error at WSAStartup().\n");
// Create a SOCKET for listening for incoming connection requests.
SOCKET sockListen;
sockListen = socket(AF_INET, SOCK_STREAM, 0);
if (sockListen == INVALID_SOCKET)
{
printf("Server: Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof (servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(5000); /* daytime server */
if (bind(sockListen, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
printf("Server: bind() failed.\n");
closesocket(sockListen);
return 0;
}
// Listen for incoming connection requests on the created socket
if (listen(sockListen, 1) == SOCKET_ERROR)
printf("Server: listen(): Error listening on socket.\n");
printf("Server: I'm listening on socket, waiting for connection...\n");
SOCKET sockConn;
char recvbuff[MAXLINE];
while (1)
{
sockConn = accept(sockListen, NULL, NULL);
recv(sockConn, recvbuff, MAXLINE, 0);
message = recvbuff;
printf("%s \n", message);
std::cout << WSAGetLastError();
Sleep(100);
memset(recvbuff, 0, MAXLINE * (sizeof recvbuff[0]));
}
WSACleanup();
return 0;
}
Client side
#include"stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include<Windows.h>
#include <time.h>
#include"iostream"
#define MAXLINE 1000
int main()
{
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
printf("Client: Error at WSAStartup().\n");
// Create a SOCKET to connect to Server.
SOCKET sockClient;
sockClient = socket(AF_INET, SOCK_STREAM, 0);
if (sockClient == INVALID_SOCKET)
{
printf("Client: Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
struct sockaddr_in servAddr;
char servHost[16];
memset(&servAddr, 0, sizeof (servAddr));
printf("Enter Host IP: ");
scanf("%s", servHost);
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(servHost);
servAddr.sin_port = htons(5000); /* daytime server */
// Connect to a server.
if (connect(sockClient, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
char buff[MAXLINE];
// Read data from server and display
connect(sockClient, (SOCKADDR*)&servAddr, sizeof(servAddr));
for (int x = 0; x < 100; x++)
{
sprintf(buff, "transmission number %d",x);
send(sockClient, buff, strlen(buff), 0);
memset(buff, 0, MAXLINE * (sizeof buff[0]));
Sleep(3000);
}
closesocket(sockClient);
WSACleanup();
closesocket(sockClient);
return 0;
}
the thing is i don't need to do the loop
sockConn = accept(sockListen, NULL, NULL);
just put it before the server loop solved and the problem solved even that am not sure why