I am a beginner at the socket programming level that's why I found some problems that may be simple. I tried to send a simple message from client to server but the command send return (-1) that's why the message not received by the server.
Also, I have the same problem in the server code and the receiver command. return (-1).
Following is my client code :
bool ClientSock() {
int sock;
struct sockaddr_in address;
sock = socket(AF_INET, SOCK_STREAM, 0);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10102);
if (connect(sock, (struct sockaddr*) &address, sizeof (address)) < 0) {
cout << "connect failed. Error \n";
return 0 ;
} else
return 1;
}
void SendComm() {
long ok;
char MESSAGE [2000];
string msg;
cout << "enter message:\t";
cin>> msg;
const char * s = msg.c_str();
int sock;
ok = send(sock, s, 1024, 0);`enter code here`
if ( send(sock,s,1024,0)< 0){//this is the problem
std::cout << "you can not send the message";
}
else{
ok = recv(sock, MESSAGE, sizeof (MESSAGE), 0);
string reply;
reply = MESSAGE;
cout << "server says:_t" << reply << endl;
}
}
int main() {
if (ClientSock()==1){
SendComm();
}
else
std::cout << "error";
}
This is my server code:
bool initialize() {
int conSock;
int ListenSock;
socklen_t addrsize;
struct sockaddr_in address;
addrsize = sizeof (address);
conSock = socket(AF_INET, SOCK_STREAM, 0);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10102);
ListenSock = socket(AF_INET, SOCK_STREAM, 0);
bind(ListenSock, (sockaddr *) & address, sizeof (address));
listen(ListenSock, SOMAXCONN);
std::cout << "server waiting for connexion\n\n ";
if (conSock = accept(ListenSock, (struct sockaddr *) &address, &addrsize) < 0) {
cout << "connect failed. Error";
return 0;
} else
return 1;
}
void Communicate() {
int conSock;
int ListenSock;
struct sockaddr_in address;
socklen_t addrsize;
long ok;
char MESSAGE[2000];
ok = recv(conSock, MESSAGE, sizeof (MESSAGE), 0);
if (recv(conSock, MESSAGE, sizeof (MESSAGE), 0)< 0){
std:: cout << "No message" ;
}
else{
string msg;
msg = MESSAGE;
cout << " client says:\t" << msg << endl;
string reply;
cout << "enter reply:\t";
cin>> reply;
const char* s = reply.c_str();
ok = send(conSock, s, 1024, 0);
}}
int main() {
if (initialize() == 1) {
Communicate();
} else
std::cout << "error ";
}
Related
I am trying to make a socket program that lets two people chat. I have one thread for sending a message and another for receiving a message. When I use cin, it cuts off the first char that I input.
I've been looking at different threads here about cin and cout being tied and not being very thread safe, but nothing has worked.
Here is my send and receive threads:
RECV
char buffer[32];
while(true)
{
memset(&buffer, 0, sizeof(buffer));
unsigned long bytes_recv;
bytes_recv = recv(socketfd, &buffer, sizeof(buffer), 0);
if(bytes_recv == 0)
{
break;
}
for(unsigned long i = 0; i < bytes_recv; i++)
{
buffer[i] = buffer[i] ^ key;
}
printf("Message Received: %s\n", buffer);
}
and Send
char buffer[32];
int conn = 1;
while(true)
{
memset(buffer, 0, sizeof(buffer));
std::cout << "Send a message to host: ";
std::cin.clear();
std::cin.getline(buffer, sizeof(buffer));
std::cout << "StrLen: " << strlen(buffer) << std::endl;
for(unsigned long i = 0; i < strlen(buffer); i++)
{
std::cout << "Char: " << buffer[i] << std::endl;
buffer[i] = key ^ buffer[i];
}
conn = send(socketfd, &buffer, strlen(buffer), 0);
if(conn == -1)
{
break;
}
}
If I type "Hello", the buffer only reads "ello" even from the cin thread.
I am trying to create a server/client communication console, but once i include the external libraries (cryptopp) and debug, it will always terminate due socket invalid error. I have no idea what is going on.
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
#include "../cryptopp565/sha.h"
using CryptoPP::SHA1;
using namespace std;
int main()
{
//initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
cerr << "Can't Initialize winsock! program terminate." << endl;
return 1;
}
//create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! program terminate." << endl;
return 1;
}
//Promtp to get server port
string server_port_temp;
cout << "Enter port : ";
cin >> server_port_temp;
int server_port = stoi(server_port_temp);
//bind the ip address and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(server_port);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&hint, sizeof(hint));
//tell winsock the socket is for listening
listen(listening, SOMAXCONN);
//wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET)
{
cerr << "Invalid socket ! program terminate." << endl;
return 1;
}
char host[NI_MAXHOST]; //client remote name
char service[NI_MAXHOST]; // service (poet client is connect on)
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXHOST, 0) == 0)
{
cout << host << " Connect on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " Connected on port " << ntohs(client.sin_port) << endl;
}
//close listening socket
closesocket(listening);
//while loop: communication
char buf[4096];
//communicate ________________
while (true)
{
ZeroMemory(buf, 4096);
//wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
cerr << "Error in recv(). Program terminate." << endl;
break;
}
if (bytesReceived == 0)
{
cout << "Client disconnected " << endl;
break;
}
cout << string(buf, 0, bytesReceived) << endl;
//echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
}
//close the socket
closesocket(clientSocket);
//clean winsock
WSACleanup();
system("pause");
return 0;
}`
I wrote a program with a simple pair of client and server,the first of which generate a bunch of strings and sends them via API provided by socket,namely sendmsg(),and the second of which receive the strings with facilitation of epoll.
According to what's captured by the tcpdump and the result of client execution,the client is able to connect to the server and send a few messages correctly,but only a few,the following strings failed to be recieved completely,and at the end of server print of the received codes there is infinite dupilcation of the same string segment.
Please contact me if any more detail is in need.
BTW,is there any recommendation of references which provide detailed description about the usage of sendmsg()?
This is main codes of client:
void MultithreadedLogAnalyzer::SendToServer(string Addr,uint16_t Port) {
int connfd = socket(AF_INET,SOCK_STREAM,0);
sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(Port);
inet_pton(AF_INET,Addr.c_str(),&servaddr.sin_addr);
/*connect failure process to be added*/
int st = connect(connfd,(struct sockaddr *)&servaddr,sizeof(sockaddr));
if(-1 == st){
perror("connection failed");
}
Handle(connfd,servaddr);
close(connfd);
}
void MultithreadedLogAnalyzer::Handle(int connfd,const sockaddr_in &servaddr){
int n= 0,counter =0;
for(vector<string>::iterator si = mFilterResult.begin();si != mFilterResult.end(); ++si)
{
msghdr msg;
iovec iov;
memset(&msg,0,sizeof(msg));
memset(&iov,0,sizeof(iov));
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
char data[1024];
memset(data,0, 1024);
memcpy(data,si->c_str(),si->size());
iov.iov_base = data;
iov.iov_len = (*si).size() ;//check first to locate error
cout << "size:" << (*si).size() << endl;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
//msg.msg_accrights = NULL;
//msg.msg_accrightslen = 0;
n = sendmsg(connfd,&msg,0);
cout << "n: " << n << endl;
++counter;
if (-1 == n)
perror("sendmsg error\n");
}
cout << "number of strings send: " << counter << endl;
The codes of server follows as below:
#include <sys/socket.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <strings.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#define POLLSIZE 100
#define STRINGSIZE 300
using namespace std;
void handle(int fd){
int c = 0;
do{
msghdr msg;
memset(&msg,0,sizeof(msghdr));
msg.msg_name = NULL;
msg.msg_namelen = 0;
char data[1024];
iovec iov;
iov.iov_base = data;
iov.iov_len = 1024;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
c = recvmsg(fd,&msg,0);
if(msg.msg_iovlen==0
){
return;
}
cout << "msg length:" << msg.msg_iovlen<< endl;
cout << string((char *)(msg.msg_iov[0].iov_base)) << endl;
}while(c != -1);
}
int main() {
int listenfd;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in servaddr,cliaddr;
socklen_t socklen = 0;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int serverPort = 2000;
servaddr.sin_port = htons(serverPort);
bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
int listennumnber = 20;
listen(listenfd,listennumnber);
//the rest to be commented
int epfd = epoll_create(POLLSIZE);
if (epfd < 0)
perror("epoll_create");
struct epoll_event ev;
ev.events = EPOLLIN|EPOLLET;
ev.data.fd = listenfd;
if(epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev) < 0)
perror("epoll_ctl");
int curfds = 1;
struct epoll_event *events = (struct epoll_event*)malloc(sizeof(struct epoll_event));
for (;;){
int n;
int nfds = epoll_wait(epfd,events,curfds,-1);
if (-1 == nfds)
continue;
for(n = 0;n < nfds; ++n){
if(events[n].data.fd == listenfd){
int connfd = accept(listenfd,(struct sockaddr *)&cliaddr ,&socklen);
cout << "connect established through connfd: " << connfd << endl;
if (connfd < 0)
continue;
// if(setnonblocking(connfd) < 0)
// perror("set setnonblocking error");
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = connfd;
if(epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev) < 0)
return -1;
curfds++;
continue;
}
handle(events[n].data.fd);
}
}
return 0;
}
Problem solved by adding send() and recv() functions in appropriate places of the message transferring loop.
cout << "msg length:" << msg.msg_iovlen<< endl;
cout << string((char *)(msg.msg_iov[0].iov_base)) << endl;
This message should only print msg.msg_iov[0].iov_len bytes.
}while(c != -1);
This is in the wrong place. It should be a test immediately after c = recvmsg(...); it should be if (c > 0), and if c == -1 you should either call perror() or use errno or strerror() in a message, immediately, without calling any other system calls.
Basically you're continuing to receive beyond end of stream; you're printing junk after end of stream or an error; and you're ignoring the actual message length when printing the message.
There is the code i am trying to implement in a client/server model but segmentation fault error is coming..
server:
/* this is the structure i am trying to pass*/
struct pkt{
char data[1000];
int seqNo;
int checksum;
void make_pkt(int seq,char dat[1000],int check)
{
seqNo=seq;
strcpy(data,dat);
checksum=check;
}
};
the main part is
main() /* main */
{
port=client_addr.sin_port;
cout<<"port : "<<port;
pkt *rcv=new pkt;
do{
cout<<"a"<<endl;
cout<<"port : "<<port;
pkt *newpkt=new pkt;
char *buffer=new char [1000];
strcpy(buffer,"Hamza");
newpkt->make_pkt(1,buffer,2);
cout<<"aa"<<endl;
client_addr.sin_port=port;
cout<<"port 2 : "<<client_addr.sin_port<<endl;
sendto(sockfd,&newpkt,sizeof(struct pkt),0,(struct sockaddr *) &client_addr,sizeof(client_addr));
cout<<"aaa"<<endl;
recvfrom(sockfd,&rcv,sizeof(struct pkt),0,(struct sockaddr *)&client_addr,&leng);
cout<<"bb :"<<rcv->seqNo<<endl;
}while(rcv->seqNo!=1);
}
client:
struct pkt{
char data[1000];
int seqNo;
int checksum;
pkt()
{
strcpy(data," ");
seqNo=0;
timer=0;
checksum=0;
}
};
main()
{
pkt *newpkt=new pkt;
do{
cout<<"aa"<<endl;
pkt *rcvpkt=new pkt;
socklen_t lengt=sizeof(my_addr);
recvfrom(sockfd,&rcvpkt,sizeof(struct pkt),0,(struct sockaddr *)&my_addr,&lengt);
cout<<"aaa"<<endl;
cout<<"aaa"<<rcvpkt->data<<endl;
newpkt->seqNo=1;
sendto(sockfd,&newpkt,sizeof(struct pkt),0,(struct sockaddr *) &my_addr,sizeof(my_addr));
}while(newpkt->seqNo!=1);
}
please tell me whats the problem in this code..?
You are not passing the struct instances to sendto() and recvfrom() correctly. Your pkt variables are pointers so you need to get rid of the & operator when passing them. You also have memory leaks. Try this instead:
main()
{
port = ntohs(client_addr.sin_port);
cout << "port : " << port;
pkt *rcv = new pkt;
do{
cout << "a" << endl;
cout << "port : " << port;
pkt *newpkt = new pkt;
char buffer[1000];
strcpy(buffer,"Hamza");
newpkt->make_pkt(1,buffer,2);
cout << "aa" << endl;
client_addr.sin_port = htons(port);
cout << "port 2 : " << ntohs(client_addr.sin_port) << endl;
sendto(sockfd, newpkt, sizeof(struct pkt), 0, (struct sockaddr *) &client_addr, sizeof(client_addr));
delete newpkt;
cout << "aaa" << endl;
recvfrom(sockfd, rcv, sizeof(struct pkt), 0, (struct sockaddr *)&client_addr, &leng);
cout << "bb :" << rcv->seqNo << endl;
}
while(rcv->seqNo != 1);
delete rcv;
}
main()
{
pkt *newpkt = new pkt;
do{
cout << "aa" << endl;
pkt *rcvpkt = new pkt;
socklen_t lengt = sizeof(my_addr);
recvfrom(sockfd, rcvpkt, sizeof(struct pkt), 0, (struct sockaddr *)&my_addr, &lengt);
cout << "aaa" << endl;
cout << "aaa" << rcvpkt->data << endl;
newpkt->seqNo = 1;
sendto(sockfd, newpkt, sizeof(struct pkt), 0, (struct sockaddr *) &my_addr, sizeof(my_addr));
delete rcvpkt;
}
while(newpkt->seqNo != 1);
delete newpkt;
}
I'm trying to port my IRC bot from Python to C++ and I'm running into some issues with Winsock2. I'm fairly new to sockets in C/C++ and most of this code was pieced together from various tutorials. I keep getting error 10049 and am at a loss. Any help would be appreciated greatly. Thanks!
port_ is set to 6667 and host_ is "irc.rizon.net"
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0) {
std::cout << "Error: " << WSAGetLastError() << " occurred!" << std::endl;
WSACleanup();
return 1;
}
std::cout << "WSAStartup Successful!" << std::endl;
socketfd_ = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (socketfd_ == INVALID_SOCKET) {
std::cout << "Error: " << WSAGetLastError() << " occurred!" << std::endl;
WSACleanup();
return 1;
}
std::cout << "Socket Creation Successful!" << std::endl;
sockaddr_in anews;
anews.sin_port = htons(port_);
anews.sin_addr.s_addr = inet_addr(host_.c_str());
anews.sin_family = AF_INET;
if (connect(socketfd_,(sockaddr*)&anews, sizeof(anews)) == SOCKET_ERROR) {
std::cout << "Error: " << WSAGetLastError() << " occurred!" << std::endl;
WSACleanup();
return 1;
}
std::cout << "Socket has connected successfuly!" << std::endl;
return 0;
inet_addr() takes a dotted IP address of the form "x.x.x.x" you are passing it the host name.
You can use gethostbyname():
hostent* host;
char* ip;
...
// Get the local host information
host= gethostbyname(host_.c_str());
ip= inet_ntoa(*(struct in_addr *)*host->h_addr_list);
sockaddr_in anews;
anews.sin_port = htons(port_);
anews.sin_addr.s_addr = inet_addr(ip);
anews.sin_family = AF_INET;
...
Or an easier route would be to use getaddrinfo():
struct addrinfo *ai;
if(getaddrinfo(host_.c_str(), "6667", NULL, &ai) != 0)
return 1;
socketfd_ = socket(ai->ai_family, SOCK_STREAM, 0);
if (socketfd_ == INVALID_SOCKET) {
freeaddrinfo(ai);
return 1
}
if (connect(socketfd_, ai->ai_addr, (int)ai->ai_addrlen) == SOCKET_ERROR) {
closesocket(socketfd_);
freeaddrinfo(ai);
return 1;
}
...