I'm writing a simple client-server application which uses async type sockets. However, when I send a message from a client, I'm getting a buffer overrun exception. Client code:
#include "stdafx.h"
#include <conio.h>
#include <winsock.h>
#include <process.h>
#include <stdlib.h>
#include <Windows.h>
#pragma comment(lib, "wsock32.lib")
#define CS_ERROR 1
#define CS_OK 0
char send_buf[1000];
char recv_buf[1000];
void MyFunction(void * Arg)
{
while(1)
{
int Socket=(*(int *)Arg);
send(Socket, send_buf,1000,0);
int n = recv(Socket,recv_buf,1000,0);
recv_buf[n]=0;
printf(" Answer from Server: %s",&recv_buf[0]);
printf("\n");
}
_endthread();
}
int _tmain(int argc, _TCHAR* argv[])
{
WORD version;
WSADATA wsaData;
int result;
version = MAKEWORD(2,2);
WSAStartup(version,(LPWSADATA)&wsaData);
LPHOSTENT hostEntry;
hostEntry = gethostbyname("127.0.0.1");
if(!hostEntry)
{
printf ("%s", " >>> ERROR (hostEntry NULL)\n");
WSACleanup();
return CS_ERROR;
}
SOCKET theSocket = socket(AF_INET, SOCK_STREAM, 0);
if(theSocket == SOCKET_ERROR)
{
printf ("%s", " ERROR (can't create socket)\n");
return CS_ERROR;
}
else
{
printf ("%s", " >>> Creating socket \n");
}
sockaddr_in serverInfo;
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
serverInfo.sin_port = htons(8888);
result=connect(theSocket,(LPSOCKADDR)&serverInfo,
sizeof(serverInfo));
if(result==SOCKET_ERROR)
{
printf ("%s", " ERROR (can't connect to Server)\n");
return CS_ERROR;
}
else
{
printf ("%s", " >>> Connecting to Server\n");
}
printf("Write a message: ");
scanf_s("%s", send_buf, sizeof(send_buf));
_beginthread(MyFunction,0,(void *)&theSocket);
char a[100];
scanf_s("%s", a, sizeof(a));
return CS_OK;
}
I suppose it has something to do with accessing send_buf\recv_buf in illegal way, but I can't figure what. Any tips?
You're not calling scanf_s properly. scanf_s requires two arguments for string input - one with the pointer to the string, and another for the maximum length of the string.
So you should call it like this:
scanf_s("%s", send_buf, sizeof(send_buf));
Related
the program main propose:
reading words from txt file and send server .
i got this eroor:
socket send failed : Connection reset by peer
// rc = send (fd, word, length, 0);
I will give you client.cpp if you want i give server.cpp
/*
g++ client.cpp -Wall -g3 -o ozgurtcpclnt
*/
using namespace std;
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "first.h"
#include <vector>
#define TCP_SERVER_PORT 54321
#define BUFFER_LENGTH 1024
const char * message = "selam dostum!";
int main () {
char word[IO_BUF_LENGTH + 1] = { 0 };
int length = 0;
FILE * fp;
fp = fopen("combinedText.txt", "r");
if (fp == NULL) {
perror("fopen failed");
return 0;
}
char buffer [BUFFER_LENGTH + 1] = {0};
int fd;
int rc;
struct sockaddr_in s_addr;
memset (&s_addr, 0, sizeof (s_addr));
fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
printf ("socket failed : %s\n", strerror (errno));
exit (1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
s_addr.sin_port = htons (TCP_SERVER_PORT);
rc = connect (fd, (struct sockaddr *)&s_addr, sizeof (s_addr));
if (rc < 0) {
printf ("connect failed : %s\n", strerror (errno));
exit (1);
}
/*length = strlen(message);
rc = send (fd, message, length, 0);*/
while (fscanf(fp, MAX_WORD_SCANF, word) != EOF) {
length = strlen(word);
if (length > 1) {
rc = send (fd, word, length, 0);
if (rc != length) {
printf (" socket send failed : %s\n", strerror (errno));
exit (1);
}
}
}
fclose(fp);
length = strlen(word);
rc = recv (fd, word,length, 0);
if (rc < 0) {
printf ("recv failed : %s\n", strerror (errno));
exit (1);
}
printf ("Server said : %s\n", word);
return 0;
}
I'm trying to implement bluetooth piconet using C programming language. I have read some papers and also gone through some examples. But i didn't get proper output. I designed server and client using following example, please check this link. Please check out the code i'm working on:
Can anyone please suggest a proper method to implement it. Thank you.
slave.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <unistd.h>
void send_message_function(char[]);
void receive_ack();
int main()
{
int i;
pthread_t thread1, thread2;
char dest1[18] = "00:1B:10:00:2A:EC";
send_message_function(dest1);
}
void send_message_function(char ptr[18])
{
//printf("MAC::%s",ptr);
struct sockaddr_l2 addr = { 0 };
int s, stat, status, i;
char dest[18], buf[1024];
int bytes_read;
strncpy(dest, ptr, 18);
// allocate a socket
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// set the connection parameters (who to connect to)
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(0x1001);
str2ba(dest, &addr.l2_bdaddr);
status = connect(s, (struct sockaddr *) &addr, sizeof(addr));
if (status == 0) {
stat = write(s, "hello!", 6);
bytes_read = read(s, buf, sizeof(buf));
if (bytes_read > 0) {
printf("received %s\n", buf);
bzero(buf, 16);
}
}
if (status < 0)
perror("uh oh");
close(s);
}
master.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
void send_ack(char[]);
int main(int argc, char **argv) {
struct sockaddr_l2 loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read,status;
socklen_t opt = sizeof(rem_addr);
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// bind socket to port 0x1001 of the first available
// bluetooth adapter
loc_addr.l2_family = AF_BLUETOOTH;
loc_addr.l2_bdaddr = *BDADDR_ANY;
loc_addr.l2_psm = htobs(0x1001);
bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
while(1){
client = accept(s, (struct sockaddr *) &rem_addr, &opt);
memset(buf, 0, sizeof(buf));
// accept one connection
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if (bytes_read > 0) {
printf("received [%s]\n", buf);
status = write(client, "acknowledgement!", 16);
}
//ba2str(&rem_addr.l2_bdaddr, buf);
//send_ack(buf);
}
close(client);
close(s);
}
This may be a duplicate question but I have read the other threads and solutions and found nothing missing in the code. Something is there which I am not able to figure out.
Below is the code for a UDP server
#pragma once
#pragma comment( linker, "/defaultlib:ws2_32.lib" )
#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <process.h>
#include <winsock.h>
#include <iostream>
#include <windows.h>
#include <string>
#include <stdio.h>
using namespace std;
#define REQUEST_PORT 0x7070
#define TIMEOUT_USEC 300000
#define MAX_RETRIES 3
int port=REQUEST_PORT;
//socket data types
SOCKET serverSocket;
SOCKET cs;
SOCKADDR_IN serverSocketAddr;
SOCKADDR_IN clientSocketAddr;
int senderAddrSize = sizeof (clientSocketAddr);
char *buffer;
char localhost[21];
HOSTENT *hp;
int main(void)
{
try
{
initializeSockets();
}
catch(char* str)
{
LPTSTR Error = 0;
if(FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,WSAGetLastError() | GetLastError(),0,(LPTSTR)&Error,0,NULL) == 0)
{
cout<<str<<endl;
}
else
{
cerr<<Error<<endl;
}
LocalFree(Error);
}
return 0;
}
void initializeSockets()
{
try
{
WSADATA wsadata;
if (WSAStartup(0x0202,&wsadata)!=0)
{
throw "Error in starting WSAStartup()";
}
else
{
buffer="WSAStartup was suuccessful\n";
}
gethostname(localhost,20);
cout<<"hostname: "<<localhost<< endl;
if((hp=gethostbyname(localhost)) == NULL)
{
cout << "Cannot get local host info."
<< WSAGetLastError() << endl;
exit(1);
}
if((serverSocket = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
throw "can't initialize socket";
serverSocketAddr.sin_family = AF_INET;
serverSocketAddr.sin_port = htons(port);
serverSocketAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (::bind(serverSocket,(LPSOCKADDR)&serverSocketAddr,sizeof(serverSocketAddr)) == SOCKET_ERROR)
throw "can't bind the socket";
if(recvfrom(serverSocket,buffer,sizeof(buffer),0,(SOCKADDR *)&clientSocketAddr, &senderAddrSize)==SOCKET_ERROR)
throw "Error";
}
catch(char* str)
{
LPTSTR Error = 0;
if(FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,WSAGetLastError() | GetLastError(),0,(LPTSTR)&Error,0,NULL) == 0)
{
cout<<str<<endl;
}
else
{
cerr<<Error<<endl;
}
LocalFree(Error);
}
}
on recvfrom I am getting the WSAError 10014: The system detected an invalid pointer address in attempting to use a pointer argument of a call.
I tried setting the last two parameters to NULL, it works fine then, which means error is in those two pointer variables. But I have properly casted the sockaddr_in to sockaddr and also initialized the length with the sizeof sockaddr. Still getting the error. Don't know what is missing.
The documentation for recvfrom() is very clear on what causes 10014 (WSAEFAULT):
WSAEFAULT
The buffer pointed to by the buf or from parameters are not in the user address space, or the fromlen parameter is too small to accommodate the source address of the peer address.
You are assigning a string literal to the buffer that you pass to recvfrom():
buffer="WSAStartup was suuccessful\n";
A string literal resides in read-only memory that recvfrom() cannot write to.
Also, buffer is declared as char*, so using sizeof(buffer) is wrong.
You need to allocate writable memory for buffer, and get rid of the useless assignment, eg:
char buffer[65535];
Then sizeof(buffer) will be meaningful.
I have been making this server and I'm using memset() to clear a struct addrinfo.
#include <iostream>
#include <string>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
#include <vector>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_CONNECTIONS 10
#define MAX_SRSIZE 500
using namespace std;
struct bcpackage{
string * message;
};
struct clientval{
int fd;
};
vector<int> file_descriptors;
WINDOW * console, * input;
void * handleClient(void * arg);
void * broadcast(void * arg);
int main(int argc, char **argv)
{
int myfd, * status;
status = new int();
struct addrinfo myaddrinfo, *res;
/****************SETUP NCURSES UI******************/
initscr();
int y, x;
getmaxyx(stdscr, y, x);
console = subwin(stdscr,y - 1, x, 0, 0);
input = subwin(stdscr,1,x,y-1,0);
wrefresh(console);
wprintw(input,">");
/**************************************************/
string port = "25544";
wprintw(console,"port: %s\n", port.c_str());
memset(&myaddrinfo, 0, sizeof(myaddrinfo));//Problem I think with this memset()
myaddrinfo.ai_family = AF_UNSPEC;
myaddrinfo.ai_socktype = SOCK_STREAM;
myaddrinfo.ai_flags = AI_PASSIVE;
wprintw(console,"Starting Server\n");
int aistat = getaddrinfo(NULL, "25544", &myaddrinfo, &res);
if( aistat == 0){
wprintw(console,"Host Information Retrieved\n");
}
else{
wprintw(console, "Error : %d\n%s\n", aistat, gai_strerror(aistat));
getch();
endwin();
exit(1);
} //We now have our address now we create a socket
myfd = socket(res->ai_family, res->ai_socktype,res->ai_protocol);
if(myfd==-1){
wprintw(console, "Socket Creation Failed\n");
wprintw(console,"Error: %d\n%s\n", errno, strerror(errno));
getch();
endwin();
exit(2);
}
//If all went well, we now have a socket for our server
//we will now use the bind() function to bind our socket
//to our program. I think that is what it does at least.
*status = bind(myfd, res->ai_addr, res->ai_addrlen);
//wprintw(console, "Status: %d\n", *status);
if((*status) < 0){
wprintw(console, "Bind failed\n");
wprintw(console,"Error: %d\n%s\n", errno, strerror(errno));
getch();
endwin();
exit(3);
}
else{
wprintw(console, "Bind success\n");
}
//Now that we are bound, we need to listen on the socket
*status = listen(myfd, MAX_CONNECTIONS);
if(status>=0){
wprintw(console, "Listening on socket\n");
}
else{
wprintw(console, "Listen failed\n");
wprintw(console,"Error: %d\n%s\n", errno, strerror(errno));
getch();
endwin();
exit(4);
}
//Everything is setup now we send the server into a loop that will pass
//each client to a new pthread.
while(true){
int *clientfd = new int();
pthread_t * cliPID = new pthread_t();
struct sockaddr_in * cliaddr = new struct sockaddr_in();
socklen_t *clilen = new socklen_t();
*clilen = sizeof(*cliaddr);
*clientfd = accept(myfd, (struct sockaddr *)cliaddr, clilen);
file_descriptors.push_back(*clientfd);
pthread_create(cliPID, NULL, handleClient, clientfd);
}
getch();
endwin();
return 0;
}
void * handleClient(void * arg){//Reads and writes to the functions
int filedesc = *((int *)arg);
string * rcvmsg = new string();
while(!read(filedesc, rcvmsg, MAX_SRSIZE)<=0){
if(rcvmsg->compare("")!=0){
wprintw(console, "Client> %s\n", rcvmsg->c_str());
broadcast(rcvmsg);
}
rcvmsg->clear();
}
delete rcvmsg;
pthread_exit(NULL);
}
void * broadcast(void * arg){
string * message = (string *)arg;
int num_fds = file_descriptors.size();
for(int i = 0; i < num_fds; i++ ){
write(file_descriptors.at(i), message, MAX_SRSIZE);
}
}
Note that this written for linux and you need to add these linker commands when compiling, -lpthread -lncurses.
The big problem is that when I have the memset() line in, the program doesn't even run things before that line. It just sits there. When I comment that line out, it actually runs.
Another error is when I do take the memset() line out, getaddrinfo() gives a ai_socktype not supported error when I use gai_strerror() to find errors with getaddrinfo(). Please help me. I'm really stuck and I don't see what's wrong.
Thanks in advance.
It's running just fine. What's happening is that when the program exits, your ncurses window is being destroyed and all its data is gone.
Add a single getch() before your return 0 and it'll magically work.
I'm having a problem with my server printing what is sent to it. I know that the data is being received because it broadcasts it back to all clients.
#include <iostream>
#include <string>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
#include <vector>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_CONNECTIONS 10
#define MAX_SRSIZE 500
using namespace std;
struct bcpackage{
string * message;
};
struct clientval{
int fd;
};
vector<int> file_descriptors;
WINDOW * console, * input;
void * handleClient(void * arg);
void * broadcast(void * arg);
void wprintr(WINDOW * win, const char * message);
int main(int argc, char **argv)
{
int myfd, * status;
status = new int();
struct addrinfo myaddrinfo, *res;
/****************SETUP NCURSES UI******************/
initscr();
int y, x;
getmaxyx(stdscr, y, x);
console = subwin(stdscr,y - 1, x, 0, 0);
input = subwin(stdscr,1,x,y-1,0);
wrefresh(console);
wprintr(input,">");
/**************************************************/
string port = "25544";
memset(&myaddrinfo, 0, sizeof(myaddrinfo));
myaddrinfo.ai_family = AF_UNSPEC;
myaddrinfo.ai_socktype = SOCK_STREAM;
myaddrinfo.ai_flags = AI_PASSIVE;//Specifies that your socket will be a passive socket that waits for connections
wprintr(console,"Starting Server");
int aistat = getaddrinfo(NULL, "25544", &myaddrinfo, &res);
if( aistat == 0){
wprintr(console,"Host Information Retrieved");
}
else{
//string message = "Error: ";
//message+=gai_strerror(aistat);
wprintr(console, gai_strerror(aistat));
endwin();
exit(1);
}
//We now have our address now we create a socket
myfd = socket(res->ai_family, res->ai_socktype,res->ai_protocol);
if(myfd==-1){
wprintr(console, "Socket Creation Failed");
getch();
endwin();
exit(2);
}
//If all went well, we now have a socket for our server
//we will now use the bind() function to bind our socket
//to our program. I think that is what it does at least.
*status = bind(myfd, res->ai_addr, res->ai_addrlen);
//wprintw(console, "Status: %d\n", *status);
if((*status) < 0){
wprintr(console, "Bind failed");
getch();
endwin();
exit(3);
}
else{
wprintr(console, "Bind success");
}
//Now that we are bound, we need to listen on the socket
*status = listen(myfd, MAX_CONNECTIONS);
if(status>=0){
wprintr(console, "Listening on socket");
}
else{
wprintr(console, "Listen failed");
getch();
endwin();
exit(4);
}
//Everything is setup now we send the server into a loop that will pass
//each client to a new pthread.
while(true){
int *clientfd = new int();
pthread_t * cliPID = new pthread_t();
struct sockaddr_in * cliaddr = new struct sockaddr_in();
socklen_t *clilen = new socklen_t();
*clilen = sizeof(*cliaddr);
*clientfd = accept(myfd, (struct sockaddr *)cliaddr, clilen);
file_descriptors.push_back(*clientfd);
pthread_create(cliPID, NULL, handleClient, clientfd);
}
wprintr(console, "Now Exiting");
getch();
endwin();
return 0;
}
void * handleClient(void * arg){//Reads and writes to the functions
int filedesc = *((int *)arg);
char buffer[MAX_SRSIZE];
char * buf = buffer;
memset(&buffer, 0, sizeof(buffer));
while(!read(filedesc, buf, sizeof(buffer))<=0){
if(strcmp(buf, "")!=0){
wprintr(console, buffer);//<- I think this is the problem Idk why though.
broadcast(&buffer);
}
memset(&buffer, 0, sizeof(buffer));
}
wprintr(console, "Client Exited");
int fdremove = -1;
for(int i = 0; i < file_descriptors.size(); i++){
if(file_descriptors.at(i)==filedesc){
file_descriptors.erase(file_descriptors.begin()+i);
wprintr(console, "File Descriptor Removed");
}
}
pthread_exit(NULL);
}
void * broadcast(void * arg){
char * message = (char *)arg;
int num_fds = file_descriptors.size();
for(int i = 0; i < num_fds; i++ ){
write(file_descriptors.at(i), message, MAX_SRSIZE);
}
}
void wprintr(WINDOW * win, const char * message){
wprintw(win, message);
wprintw(win, "\n");
wrefresh(win);
}
This is written for Linux and needs -lpthread and -lncurses to compile. When you run the server you can telnet to it to test it. I know that data is being received because it is getting broadcasted back to all of the clients however the data received is not being printed on the server's screen. I think it may be an issue with ncurses but I don't know. I believe the problem is in my handleClient function.
Thanks in advance.
telnet sends "\r\n" at the end of every line. If you don't remove those characters every line you print is instantly overwritten.
I think it's bad idea to use ncurses in a server. Usually you want to save a log to a file, which would be very hard if you use ncurses. And, you will run into problems like this, because you cannot tell exactly what your program is outputting.