Reputation: 91
OK so I have a server & client using sockets and threading.
Server:
<Includes>...
struct sockaddr_in server;
int sock,rvsock;
int port,max,k = 0, len;
char buff[1024];
pthread_t thr[100];
void handler(int sig)
{
if(close(rvsock) < 0)
{
perror("Close.");
return;
}
}
void *worker (void* a)
{
k=0;
int ar[3];
int i=0;
char Smax[1024];
char *token;
recv(sock,&buff,sizeof(buff),0);
token = strtok(buff," ");
while(token && token!=" ")
{
int nr = atoi(token);
ar[i]=nr;
k=k+nr;
i++;
token = strtok(NULL," ");
}
if (k > max)
{
printf ("%d is indeed > than %d\n",k,max);
max=k;
}
printf("Current max is %d\n",max);
char temp[1024];
sprintf(temp,"%d",max);
strcpy(Smax,"The current maximum is: ");
strcat(Smax,temp);
strcat(Smax," and the numbers are: ");
for (i=0;i<3;i++)
{
sprintf(temp,"%d",ar[i]);
strcat(Smax,temp);
strcat(Smax," ");
}
printf ("%s\n",Smax);
send(sock, &Smax, sizeof(Smax), 0);
close(sock);
}
int main (int argc,char* argv[])
{
int i=0;
if (argc < 2)
{
perror ("No port assigned.");
exit(0);
}
else
{
sscanf (argv[1],"%d",&port);
}
/* Creating socket (AF_INET - TCP/IP) */
rvsock = socket (AF_INET,SOCK_STREAM,0);
if (rvsock<0)
{
perror("Socket was not created.");
}
memset(&server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(port);
/* Binding socket */
if( bind(rvsock,(struct sockaddr*)&server,sizeof(server))<0)
perror("Error in binding socket");
else
{
printf("Server established.\nAwaying clients.\n");
}
/* Listening */
if (listen(rvsock,5)<0)
perror("Error in listening");
len = sizeof(server);
signal(SIGINT,handler);
/* Accepting and threading */
while(1 && i<100){
sock = accept (rvsock,(struct sockaddr*)&server,(socklen_t * __restrict__) &len);
if (sock<0)
{
perror("Error in accepting socket");
break;
}
pthread_create(&thr,NULL,worker,i);
i++;
}
int j;
/* Joining threads */
for (j=0;j<100;j++)
pthread_join(thr,NULL);
return 0;
ClientSide:
int main(int argc,char* argv[])
{
int sock;
int k,port;
char len[1024];
char buff[1024];
struct sockaddr_in server;
if (argc<2)
{
perror ("Invalid number of args");
exit(0);
}
else
{
sscanf(argv[1],"%d",&port);
randomize(buff);
}
sock = socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
perror("Socket creation failure");
memset(&server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr("127.0.0.1");
server.sin_port=htons(port);
if (connect(sock,(struct sockaddr*)&server,sizeof(server))<0)
perror("Connection error");
printf("Sending input: %s\n",buff);
send(sock,buff,sizeof(buff),0);
while(1)
{
k = recv(sock,&len, sizeof(len),0);
if(k<=0)
break;
printf("Got back %s \n",len);
}
close(sock);
return 0;
The server has a worker function that sends back data to the client. I need to include in that data the IP and Port of the client.
How can I get that ?
Upvotes: 1
Views: 14673
Reputation: 914
In your code at:
sock = accept (rvsock,(struct sockaddr*)&server,(socklen_t * __restrict__) &len);
You're overwriting the contents of server
with the client information. len
is also being overwritten with the size of what was overwritten in server
. You need to do something like this instead to receive the client socket information (taken from Beej's networking guide):
struct sockaddr_storage their_addr;
socklen_t addr_size;
struct addrinfo hints, *res;
int sockfd, new_fd;
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
getaddrinfo(NULL, MYPORT, &hints, &res);
// make a socket, bind it, and listen on it:
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockfd, res->ai_addr, res->ai_addrlen);
listen(sockfd, BACKLOG);
// now accept an incoming connection:
addr_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);
// ready to communicate on socket descriptor new_fd!
Paragraph from man 2 accept
:
The argument address is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the address parameter is determined by the domain in which the communication is occurring. The address_len is a value-result parameter; it should initially contain the amount of space pointed to by address; on return it will contain the actual length (in bytes) of the address returned. This call is used with connection-based socket types, currently with SOCK_STREAM.
Upvotes: 3