I'm writing a simple program to transfer files from server to client (both on the same computer for now). Using "telnet 127.0.0.1 [port]", I can succesfully get the file from the server, but when I run the client, the server refuses connection. I suspect that the client is trying to connect to the wrong address, but I'm not sure. I also added some GDB test output if it helps.
Server: "./server 0 4100 bigfile 100 0.01"
int main(int argc, char* argv[])
{
int sockfd;
if(!(sockfd = socket(AF_INET, SOCK_STREAM, 0))) {
error("Failed to create socket");
}
struct sockaddr_in serv_addr, cl_addr;
bzero((void*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(atoi(argv[2]));
if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
error("Failed to bind");
}
listen(sockfd, 10);
int fd = open(argv[3], O_RDONLY);
int bufsize = atoi(argv[4]);
int packet_period = atoi(argv[5]);
size_t cl_addr_len = sizeof(cl_addr);
char *buf = new char[bufsize];
while(true) {
int sd;
cout << "waiting for client..." << endl;
if(!(sd = accept(sockfd, (struct sockaddr *) &cl_addr, (socklen_t*) &cl_addr_len))) {
error("Failed to acccept");
}
cout << "Accepted client connection" << endl;
lseek(fd, 0, SEEK_SET);
while(int n = read(fd, buf, bufsize)) {
cout << "Transferring " << buf << endl;
usleep(100000);
write(sd, buf, n);
}
}
}
Client: "./client 0 127.0.0.1 4100 bigfile stats"
int main(int argc, char *argv[])
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("Failed to open socket");
}
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[2]);
serv_addr.sin_port = htons(atoi(argv[3])); // I tried both htons and htonl
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
error("Failed to connect");
}
int n;
char buf[256];
int fd = open(argv[4], O_RDONLY);
while((n = read(sockfd, buf, 256)) > 0) {
printf("Received: %s\n", buf);
write(fd, buf, n);
}
close(fd);
close(sockfd);
return 0;
}
GDB Output:
(gdb) r
Starting program: [...]/client 0 127.0.0.1 4100 bigfile stats
Breakpoint 1, main (argc=6, argv=0x7fffffffde68) at client.cpp:31
31 if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
(gdb) p serv_addr
$1 = {sin_family = 2, sin_port = 0, sin_addr = {s_addr = 16777343},
sin_zero = "\000\000\000\000\000\000\000"}
{sin_family = 2, sin_port = 0, sin_addr = {s_addr = 16777343}, sin_zero = "\000\000\000\000\000\000\000"}
So sin_port is wrong: it shouldn't be zero. The code that sets it is:
serv_addr.sin_port = htonl(atoi(argv[3]));
The problem is here. It should be
serv_addr.sin_port = htons(atoi(argv[3]));
Not today's problem but
printf("Received: %s\n", buf);
should be
printf("Received: %.*s\n", n, buf);
Related
I'm trying to write through a socket using its descriptor. I have used bind() to bind the socket to the address I want. Whenever I'm using sendto() everything is OK. But whenever I'm using write() (or send()) I'll face Destination address required(errno 89).
What I'm trying to do is to write through the socket using iovec. In this case we don't have any alternative for writev() to get destination address. As I don't want to connect every single time, I was wondering whether I can do it without having to use connect() or accept() syscalls.
Here is the code I wrote:
int sock = 0;
struct sockaddr_in serv_addr;
char *hello = "chetori to";
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
int opt = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
string interface_name = "lo";
ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", interface_name.c_str());
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, reinterpret_cast<void*>(&ifr), sizeof(ifr)) < 0)
throw exception(); // Imaginary exception
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
string interface_address = "127.0.0.1";
if (inet_aton(interface_address.c_str(), &serv_addr.sin_addr) == 0)
throw exception(); // Imaginary exception
serv_addr.sin_port = htons(PORT);
if (bind(sock, reinterpret_cast<sockaddr*>(&serv_addr), sizeof(serv_addr)) < 0)
throw exception(); // Imaginary exception
char f[1024] = "Hello there";
char sec[1024] = "How are you";
char th[1024] = "I'm fine";
char fh[1024] = "Bye bye";
struct iovec bufs[] = {
{ .iov_base = f, .iov_len = sizeof(f) },
{ .iov_base = sec, .iov_len = sizeof(sec) },
{ .iov_base = th, .iov_len = sizeof(th) },
{ .iov_base = fh, .iov_len = sizeof(fh) },
};
int iovcnt = sizeof(bufs) / sizeof(struct iovec);
writev(sock, bufs, iovcnt);
Note that Interface name and IP address have no problem and are correct.
I am trying to create a client server application in linux. Server sends object to client but client write Segmentation fault. Here is the code.
Snake is class where is two-dimensional array.
Client send message "p" and server is creating object witch will be send to client.
Server side:
int main(int argc, char *argv[])
{
int sockfd, newsockfd;
socklen_t cli_len;
struct sockaddr_in serv_addr, cli_addr;
int n;
char buffer[256];
if (argc < 2)
{
fprintf(stderr,"usage %s port\n", argv[0]);
return 1;
}
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(atoi(argv[1]));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("Error creating socket");
return 1;
}
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("Error binding socket address");
return 2;
}
while(sockfd){
listen(sockfd, 5);
cli_len = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
if (newsockfd < 0)
{
perror("ERROR on accept");
return 3;
}
bzero(buffer,256);
n = read(newsockfd, buffer, 255);
if (n < 0)
{
perror("Error reading from socket");
return 4;
}
// if client send 'p'
if(*buffer == 'p' ){
Snake *snake = new Snake();
send(newsockfd,reinterpret_cast<const char*>(&snake), sizeof(snake),0);
}
}
//printf("Here is the message: %s\n", buffer);
const char* msg = "I got your message";
n = write(newsockfd, msg, strlen(msg)+1);
if (n < 0)
{
perror("Error writing to socket");
return 5;
}
close(newsockfd);
close(sockfd);
}
Client side:
int main(int argc, char *argv[])
{
int sockfd = 0,newsockfd, n;
struct sockaddr_in serv_addr;
struct hostent* server;
socklen_t cli_len, serv_len;
char buffer[999999];
struct sockaddr_in cli_addr;
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
return 1;
}
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr, "Error, no such host\n");
return 2;
}
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy(
(char*)server->h_addr,
(char*)&serv_addr.sin_addr.s_addr,
server->h_length
);
serv_addr.sin_port = htons(atoi(argv[2]));
//while(sockfd >= 0){
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("Error creating socket");
return 3;
}
if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("Error connecting to socket");
return 4;
}
printf("Please enter a message: ");
bzero(buffer,256);
fgets(buffer, 255, stdin);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
{
perror("Error writing to socket");
return 5;
}
Snake *snake ;
recv(sockfd,reinterpret_cast<char*>(&snake), sizeof(snake),0);
if (n < 0)
{
perror("Error reading from socket");
return 6;
}
printf("%s\n",buffer);
close(sockfd);
close(newsockfd);
return 0;
}
Thank you for your answers.
On the client side
Snake *snake ;
recv(sockfd,reinterpret_cast<char*>(&snake), sizeof(snake),0);
tries to read into a Snake, but you haven't created any. So the uninitialized pointer gives you the segmentation fault.
Also, sizeof(snake) is the size of a pointer (like 4 bytes), not the size of the object pointed to. This occurs both in the server and in the client.
I have two programs, on is server and only listening and the client is talking. I send 1mbytes of data in chunks of 64bytes each. I will get the first chunk of 64byte but then my server exits because it failed to get other data. My client is sending all of the data.
void ServerLinux::Receive(){
int sock = 0;
struct sockaddr_in server;
char buffer[this->packageLength];
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
this->Die("Failed to create socket");
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(this->port);
if(bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0){
this->Die("Failed to bind the server socket");
}
if(listen(sock, 1) < 0){
this->Die("Failed to listen on server socket");
}
int clientSocket = 0;
struct sockaddr_in client;
socklen_t size = sizeof(client);
if((clientSocket = accept(sock, (struct sockaddr *) &client, &size)) < 0){
this->Die("Failed to accept client");
}
int received = -1;
//This is fine data is recived
if((received = recv(clientSocket, buffer, this->packageLength,0)) < 0){
this->Die("Failed to receive initial bytes from client");
}
std::cout << "Received!" << std::endl;
//Data is not received in this while loop
while(received > 0){
if((received = recv(sock, buffer, this->packageLength,0)) < 0){
this->Die("Failed to receive additional bytes frin client");
}
std::cout << "Received!" << std::endl;
}
}
Why don't you use the same arguments for recv?
works: recv(clientSocket, buffer, this->packageLength,0)
doesn't work recv(sock, buffer, this->packageLength,0)
Change sock to clientSocket.
First time here. I'm trying to implement an UDP Socket client/server to work with BGI for my college exam. I want to send the move coordinates and receive a test char. But when I use recvfrom() it doesn't work, without it works fine. Sorry about my english.
Here's the client file:
#define WIN32_LEAN_AND_MEAN
#include<winsock2.h>
#include<windows.h>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<graphics.h>
#define SIZE 512
#define PORT 20252
#define SERVER_IP "127.0.0.1"
#define CLIENT_IP "127.0.0.1"
using namespace std;
int main() {
WSADATA wsaData;
SOCKET ClientSocket;
int server_length;
struct sockaddr_in server;
struct sockaddr_in client;
char print_buffer[SIZE];
/* ==================================================================================*/
WSAStartup(0x0101, &wsaData);
ClientSocket = socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
memset((void *)&client, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
client.sin_family = AF_INET;
client.sin_port = htons(PORT);
client.sin_addr.s_addr = inet_addr(CLIENT_IP);
bind(ClientSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in));
/* ==================================================================================*/
int x = 0;
while (x != 1) {
server_length = sizeof(struct sockaddr_in);
if (GetKeyState(VK_RIGHT)&0x80) {
char send_right_P1[SIZE] = "P1RIGHT\r\n";
sendto(ClientSocket, send_right_P1, (int)strlen(send_right_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_right_P1[0], 0, sizeof(send_right_P1));
}
if (GetKeyState(VK_LEFT)&0x80) {
char send_left_P1[SIZE] = "P1LEFT\r\n";
sendto(ClientSocket, send_left_P1, (int)strlen(send_left_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_left_P1[0], 0, sizeof(send_left_P1));
}
if (GetKeyState(VK_UP)&0x80) {
char send_up_P1[SIZE] = "P1UP\r\n";
sendto(ClientSocket, send_up_P1, (int)strlen(send_up_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_up_P1[0], 0, sizeof(send_up_P1));
}
if (GetKeyState(VK_DOWN)&0x80) {
char send_down_P1[SIZE] = "P1DOWN\r\n";
sendto(ClientSocket, send_down_P1, (int)strlen(send_down_P1) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_down_P1[0], 0, sizeof(send_down_P1));
}
if (GetKeyState(VK_ESCAPE)&0x80) {
char send_escape[SIZE] = "ESCAPE\r\n";
sendto(ClientSocket, send_escape, (int)strlen(send_escape) + 1, 0, (struct sockaddr *)&server, server_length);
memset(&send_escape[0], 0, sizeof(send_escape));
}
recvfrom(ClientSocket, print_buffer, SIZE, 0, (struct sockaddr *)&server, &server_length);
if (strcmp(print_buffer, "TESTE\r\n" ) == 0) {
cout << print_buffer;
} else cout << "Failed\n";
memset(&print_buffer[0], 0, sizeof(print_buffer));
delay(50);
}
closesocket(ClientSocket);
WSACleanup();
return 0;
}
Here's the server:
#define WIN32_LEAN_AND_MEAN
#include<winsock2.h>
#include<windows.h>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<graphics.h>
#include "images.h"
#define SIZE 512
#define PORT 20252
#define SERVER_IP "127.0.0.1"
#define CLIENT_IP "127.0.0.1"
using namespace std;
int main() {
WSADATA wsaData;
SOCKET ServerSocket;
int client_length;
struct sockaddr_in server;
struct sockaddr_in client;
char Player1_Buffer[SIZE];
/* ==================================================================================*/
initwindow(800, 600);
int pg = 2, passo = 5, fim = 0;
GetImages();
int Pos1X = 200, Pos1Y = 300, direction1 = 1;
int Pos2X = 600, Pos2Y = 300, direction2 = 1;
/* ==================================================================================*/
WSAStartup(0x0101, &wsaData);
ServerSocket = socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
memset((void *)&client, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = inet_addr(SERVER_IP);
client.sin_family = AF_INET;
client.sin_port = htons(PORT);
client.sin_addr.s_addr = inet_addr(CLIENT_IP);
bind(ServerSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
printf("Server running on %u.%u.%u.%u\n", (unsigned char)server.sin_addr.S_un.S_un_b.s_b1,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b2,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b3,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b4);
printf("Press CTRL + C to quit\n");
while (fim != 1) {
if (pg == 1) pg = 2; else pg = 1;
setactivepage(pg);
cleardevice();
putimage(0, 0, background, OR_PUT);
drawBoy(Pos1X, Pos1Y, direction1);
setvisualpage(pg);
delay(50);
client_length = (int)sizeof(struct sockaddr_in);
recvfrom(ServerSocket, Player1_Buffer, SIZE, 0, (struct sockaddr *)&client, &client_length);
if (strcmp(Player1_Buffer, "P1RIGHT\r\n") == 0) {
Pos1X = Pos1X + passo;
direction1 = 3;
cout << "Received from Player1: " << Player1_Buffer << endl;
}
if (strcmp(Player1_Buffer, "P1LEFT\r\n" ) == 0) {
Pos1X = Pos1X - passo;
direction1 = 4;
cout << "Received from Player1: " << Player1_Buffer << endl;
}
if (strcmp(Player1_Buffer, "P1UP\r\n" ) == 0) {
Pos1Y = Pos1Y - passo;
direction1 = 2;
cout << "Received from Player1: " << Player1_Buffer << endl;
}
if (strcmp(Player1_Buffer, "P1DOWN\r\n" ) == 0) {
Pos1Y = Pos1Y + passo;
direction1 = 1;
cout << "Received from Player1: " << Player1_Buffer << endl;
char print_buffer[SIZE] = "TESTE\r\n";
sendto(ServerSocket, print_buffer, (int)strlen(print_buffer) + 1, 0, (struct sockaddr *)&client, client_length);
}
if (strcmp(Player1_Buffer, "ESCAPE\r\n") == 0) {
fim = 1;
cout << "Received from Player1: " << Player1_Buffer << endl;
}
}
closesocket(ServerSocket);
WSACleanup();
return 0;
}
Don't bind() the socket on the client. You're binding the client socket to 127.0.0.1:20252, then sending data to the same address:port pair.
Just remove the call to bind() in the client code.
Another option (also on the client) is to bind to port 0, which will assign an unused port.
Also: Check the return values from bind(), sendto(), recvfrom(), etc and display the error code if they fail.
One more: The length parameter to recvfrom() must be initialized before the call. For example, in the client you should do this:
server_length = sizeof(server);
recvfrom(ClientSocket, print_buffer, SIZE, 0, (struct sockaddr *)&server, &server_length);
Likewise on the server side.
I started making a C++ server, but I can't bind to socket.
#pragma once
#include <WinSock2.h>
#include <thread>
#include "Logging.h"
namespace network
{
static SOCKET sock;
static VOID startAccept()
{
while (true)
{
struct sockaddr_in serv_addr, cli_addr;
int clilen = sizeof(cli_addr);
SOCKET accepted;
if (accepted == NULL)
{
accepted = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
if (accepted < 0)
{
core::writeln("Error accept: " + WSAGetLastError());
}
else
{
core::writeln("New connection from " + cli_addr.sin_addr.S_un.S_addr);
}
}
}
}
static VOID connect(const char* ipAddress, u_short port)
{
struct sockaddr_in serv_addr, cli_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
{
core::writeln("Error creating socket: " );
perror("error:");
return;
}
else if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
core::writeln("Error binding to socket: " );
perror("error:");
return;
}
else if (listen(sock, 10) < 0)
{
core::writeln("Error listening socket: ");
return;
}
else
{
core::writeln("Bound WinSock to " + serv_addr.sin_addr.S_un.S_addr);
std::thread accepting(startAccept);
accepting.join();
}
}
};
In my main int:
int _tmain(int argc, _TCHAR* argv[])
{
connect("127.0.0.1", 500);
}
But everytime I try to bind, I get the following output:
Error binding to socket:
error:No Error
But the socket isn't bound on. What am I doing wrong?
FIXED, had to use WSAStartup.