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.
Related
I have been trying to understand why on my server the accept() call is still blocking when the client has a successful connect() call?
server.cpp
#include <errno.h>
#include <strings.h>
#include <iostream>
#include "globals.h"
using namespace std;
/* Declaring errno */
extern int errno;
/* Function for printing error */
void report_error(char *s)
{
printf("receiver: error in%s, errno = %d\n", s, errno);
exit(1);
}
int main(int argc, char *argv[])
{
int s,c;
int res;
struct sockaddr_in socket_address = {0}, client_sa = {0};
unsigned int client_sa_len = sizeof(client_sa);
/* Creating the socket and returns error if unsuccesfull */
if((s= socket(AF_INET, SOCK_DGRAM, PF_UNSPEC)) == -1)
report_error("socket");
socket_address.sin_family = AF_INET;
socket_address.sin_addr.s_addr=INADDR_ANY;
socket_address.sin_port = htons(5318 + 2000);
/* Binding the socket and returns error if unsuccesfull */
if(bind(s, (struct sockaddr *)&socket_address, sizeof(socket_address))== -1)
report_error("bind");
listen(s, 10);
cout << "listening on port\n";
while(1)
{
/*The server just hangs here*/
c = accept(s, (struct sockaddr*)&client_sa, &client_sa_len);
if (c > 0)
{
cout << "LOG: Was the accept successful" << endl;
res = fork();
if (res < 0)
{
perror("Forking of child failed");
}
}
if(res == 0)
{
//close(s);
char msg[MSGL], reply[50], args[MSGL];
char command[MSGL];
cout << "LOG: Get message?" << endl;
GetRequest(msg, c, &client_sa);
if( (msg[0] == 'c') && (msg[1] == 'd') && (msg[2] == ' '))
{
strncpy(command, "cd", sizeof(command));
int arg_i = 0;
for(int i = 3; msg[i] != '\n'; ++i)
{
args[arg_i] = msg[i];
++arg_i;
}
}
else
{
for(int i = 0; msg[i] != '\n'; ++i)
{
command[i] = msg[i];
}
}
else
{
if(c > 0)
{
//close(c);
}
}
}
return 0;
}
When I run this server it prints that it is listening, then when I initialize the client it does not say that the client has connected
client.cpp
#include <errno.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
#include "globals.h"
using namespace std;
/* Declaring errno */
extern int errno;
int main(int argc, char *argv[])
{
int s;
char* server_address = argv[1];
char command[MSGL];
char reply[MSGL];
int connect_success;
struct sockaddr_in sa = {0} ,cli_sa = {0};
int length = sizeof(sa);
struct hostent *hp;
cli_sa.sin_family = AF_INET;
cli_sa.sin_addr.s_addr=INADDR_ANY;
cli_sa.sin_port = htons(5318 + 2001);
/* FILL SOCKET ADDRESS*/
if((hp = gethostbyname(server_address))==NULL)
report_error("gethostbyname");
bcopy((char*)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
//memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
sa.sin_port = htons(5318 + 2000); /* define port number based on student ID*/
/* Creating the socket and returns error if unsuccessfull */
if((s=socket(AF_INET, SOCK_DGRAM, PF_UNSPEC))== -1)
report_error("socket");
/* Binding the socket and returns error if unsuccesfull */
if(bind(s, (struct sockaddr *)&cli_sa, sizeof(cli_sa))== -1)
report_error("bind");
connect_success = connect(s,(struct sockaddr*) &sa, length);
cout << connect_success << endl;
if (connect_success < 0)
{
report_error("connect");
cout << "LOG: is there an error?" << endl;
}
cout << "LOG: is the connection made?" << endl;
while(1)
{
cout << "myRPC>>";
fgets(command,MSGL,stdin);
if (DoOperation(command,reply,s,sa) == SEND_FAILURE)
{
cout << "Error: sending command\n";
}
}
return 0;
}
I'm fairly certain that your server process has undefined behavior.
accept() and connect() is for TCP sockets. You are creating UDP sockets. For UDP sockets, all that connect() does is set the default address for send(), and it always succeeds immediately. This is explained in the manual page for connect(2), which you should definitely read:
If the socket sockfd is of type SOCK_DGRAM, then addr is the address
to which datagrams are sent by default, and the only address from
which datagrams are received.
I expect accept() to fail for UDP (SOCK_DGRAM) sockets, most likely with EINVAL. If you review the logic in your server code, when accept() fails, res never gets initialized before its value is tested in the if() statement.
Undefined behavior.
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));
I have written a C++ demo example. It transfers a file from a server to client.When, I run this program in the local host, it works fine. However, when I run this program over the network the file transfer is incorrect. The image size received is larger than the image size sent. Also, why the same works on the local host? I have tried changing the port number also.
Here is the program -
Server
/** man 2 socket **/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char msg[] = "Shreyas..first socket prog";
int sock , sock_active;
struct sockaddr_in server, client;
int sent,ret;
unsigned int len;
char buffer[1024];
FILE *fp;
if ( (sock = socket(AF_INET,SOCK_STREAM,0)) == -1 )
//if ( (sock = socket(AF_INET,SOCK_DGRAM ,0)) == -1 )
{
perror("Sock:");
}
server.sin_family = AF_INET;
server.sin_port = htons(15000);
//server.sin_addr.s_addr = INADDR_ANY;
inet_aton("136.170.195.17", &(server.sin_addr));
bzero(&server.sin_zero, 8);
len = sizeof(struct sockaddr_in);
if( ret = (bind( sock, (struct sockaddr *)&server, len)) == -1 )
{
perror("bind :");
}
ret = listen(sock, 0);
while(1)
{
if( (sock_active = accept(sock, (struct sockaddr *)&client, &len)) == -1 )
{
perror("Problem in active socket:");
}
fp = fopen("./Tiger.JPG","rb");
if( fp == NULL )
{
cout<<"Error open file";
return -1;
}
memset(buffer, 1024,0);
int packets = 0;
int count;
//while ( fgets(buffer,1024,fp ) != NULL )
while( ! feof(fp) )
{
packets++;
cout<<"Client IP address is "<<inet_ntoa(client.sin_addr)<<endl;
cout<<"Client Port address is "<<ntohs(client.sin_port)<<endl;
/** Fread is reliable when using to find out the EOF , in feof(fp **/
count = fread(buffer,1,sizeof(buffer),fp);
/** fgets doesn't move the FP correctly */
//fgets(buffer,sizeof(buffer),fp);
cout<<"Read number of bytes ="<<count;
sent = send(sock_active, buffer, sizeof(buffer),0);
cout<<"The number of bytes sent ="<<sent<<"packet number = "<<packets<<endl;
memset(buffer, 1024,0);
}
cout<<"CLose current socket"<<endl;
close(sock_active);
fclose(fp);
}
cout<<"CLosing socket now" <<endl;
close(sock);
return 0;
}
Client socket program -
/** man 2 socket **/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <unistd.h>
using namespace std;
int main(int argc, char *argv[])
{
struct sockaddr_in server;
int ret;
int sock;
int read_val = 1;
unsigned int len;
if ( (sock = socket(AF_INET,SOCK_STREAM,0)) == -1 )
{
perror("Sock:");
}
if( argc != 2 )
{
cout<<"Pass the Server IP "<<endl;
exit(EXIT_FAILURE);
}
server.sin_family = AF_INET;
server.sin_port = htons(15000);
inet_aton(argv[1], &(server.sin_addr));
bzero(&server.sin_zero, 8);
len = sizeof(server);
if ( (ret = connect(sock, (struct sockaddr *)&server,sizeof(server))) == -1)
{
perror("Connect failed:");
exit(-1);
}
char msg[1024];
memset(msg,0,1024);
FILE *fp_w;
fp_w = fopen("./try.JPG","wb");
while( read_val)
{
read_val = recv(sock,(char *)msg,sizeof(msg),0);
fwrite(msg,1,sizeof(msg),fp_w);
}
cout<<"Read is complete"<<endl;
fclose(fp_w);
close(sock);
return 0;
}
May be you should modify this block of code in your client.
while( read_val)
{
read_val = recv(sock,(char *)msg,sizeof(msg),0);
fwrite(msg,1,sizeof(msg),fp_w);
}
recv function will not always receive the number of bytes you want to receive. You have to use the return value of recv to know the number of bytes actually read and use that count to write to file.
I would write this block as,
while( read_val)
{
read_val = recv(sock,(char *)msg,sizeof(msg),0);
if ( read_val > 0)
{
fwrite(msg,1,read_val,fp_w); // I am using `read_val` while writing.
}
}
While working with file/socket io APIs, its not good to assume that it read/wrote exact number of bytes you asked to.
You are making the usual mistake of assuming that recv(), fread(), etc. fill the buffer. They aren't required to do that. They return a count of the number of bytes that were actually received. You have to use that count as the length argument when sending,
You have to send actual number of bytes read:
count = fread(buffer,1,sizeof(buffer),fp);
cout<<"Read number of bytes ="<<count;
if ( count > 0)
sent = send(sock_active, buffer, count,0);
The same for the client while reading:
while( read_val)
{
read_val = recv(sock,(char *)msg,sizeof(msg),0);
if ( read_val > 0) {
fwrite(msg,1,read_val,fp_w)
} else if ( red_val == -1) {
// an error has occured
break;
} else {
// peer has closed the connection
break;
{
}
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 new to socket programming and I have this client that tries to connect to a server on the same computer. But the server hangs there after bind or accept—cause bind seems to be right but no output. I know that the server works because another client can connect just fine and the client seems to have done that. What causes the server to not see this incoming connection? I'm at the end of my wits here.
And I haven't been used to programming on Mac, so thank you so much for your patience if I have made some foolish mistakes.
My code is as follows:
server.cpp
using namespace std;
#include<iostream>
#include <netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define PORT 8888
#define BACKLOG 20
//#define DEST_IP "127.0.0.1"
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
int main(int argc,char *argv[])
{
//cout<<"?";
int ss, sc, r, err;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int opt=1;
pid_t pid;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
ss = socket(AF_INET, SOCK_STREAM, 0);
if(ss<0)
{
cout<<"[process infro]socket error"<<endl;
return -1;
}
cout<<"[process infro]socket successful"<<endl;
r = setsockopt(ss, SOL_SOCKET,SO_REUSEADDR, (void*)&opt,sizeof(opt));
if (r == -1)
{
perror("setsockopt(listen)");
return 0;
}
cout<<"[process infro]sockopt successful"<<endl;
cout<<"?";
err = bind(ss, (struct sockaddr*) &server_addr, sizeof( server_addr));
cout<<"err";
if(err < 0)
{
cout<<"[process infro]bind error"<<endl;
return -1;
}
cout<<"[process infro]bind successful";
err=listen(ss, BACKLOG);
if(err <0)
{
cout<<"[process infro]listen error"<<endl;
return -1;
}
cout<<"[process infro]lisen successful";
for( ; ; )
{
int addrlen = sizeof(struct sockaddr);
sc = accept(ss, (struct sockaddr*)&client_addr, (socklen_t *)&addrlen);
if(sc < 0)
{
continue;
}
pid = fork();
if (pid == 0)
{
close(ss);
process_conn_server(sc);
}
else
{
close(sc);
}
}
//opt=0;
//setsockopt(ss,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(len));
}
client.cpp
using namespace std;
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <arpa/inet.h>
#include <fstream.h>
#define PORT 8888
#define DEST_IP "127.0.0.1"
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
write(s,buffer,1024);
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close(); //关闭文件
}
int main(int argc,char *argv[])
{
int s;
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(DEST_IP);
server_addr.sin_port = htons(PORT);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0)
{
cout<<"[process infro]socke error"<<endl;
return -1;
}
cout<<"[process infro] socket built successfully\n";
//inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
cout<<"[process infor] connected\n";
process_conn_client(s);
close(s);
return 0;
}
This may be unrelated.... but it won't fit in a comment...
In your server you do this:
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
// keep reading until read returns 0
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
In your client you do this:
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
// write to server?
write(s,buffer,1024);
// read from server?
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close();
}
It's a bit hard to follow because of your variable names, but it looks like your client is working under the assumption that your server will send back a response for every chunk of data received, which isn't the case. You server doesn't appear to have changed the accepted socket to non-blocking, so it's going to block on the read call until there is some data to read (it's never going to get 0)...
Are you sure it's failing before this point? Do you have some sample output?
Aso, in your call to accept, you pass addrlen...
int addrlen = sizeof(struct sockaddr);
I think this should be:
int addrlen = sizeof(struct sockaddr_in); /* sizeof(client_addr) */