So I'm doing some client server stuff here, and I want my server to listen for clients, and when a client connects to the server, the client sends a string.
The connection establishes, the clients sends it's string, but, at server side, recv() returns -1.
/* Server */
int main() {
int fd, conn_fd;
struct sockaddr_in ad;
int bytes;
char recv_buffer[256];
fd = socket(AF_INET, SOCK_STREAM, 0);
ad.sin_family = AF_INET;
ad.sin_port = htons(3335);
ad.sin_addr.s_addr = htonl(INADDR_ANY);
bind(fd, (struct sockaddr*)&ad, sizeof(ad));
listen(fd, 5);
conn_fd = accept(fd, (struct sockaddr*)0, 0);
bytes = recv(fd, recv_buffer, sizeof(recv_buffer), 0);
printf("%d\n", bytes);
return 0;
}
The clients simply connects to the server:
/* Client */
int main() {
int fd, n;
unsigned int s;
struct sockaddr_in addr;
fd = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(3335);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
char buff[256] = "time";
printf("Connecting to server....\n");
if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
printf("connect() error.\n");
exit(1);
}
s = send(fd, buff, sizeof(buff), 0);
return 0;
}
Thanks!
I found out what the problem was. In my server code, I was using the wrong socket descriptor for recv(): instead of fd, I should have used conn_fd.
Related
I'm trying to make a program that uses sockets between a client and a server. In my code below if I comment on the loop while my server receives my message but if I do not comment my client seems not to send my message (finally my server never receives my message). Why ?
Server
int main()
{
message = malloc(sizeof(char));
printf("Waiting for incoming connections ...\n");
sem_init(&lock, 0, 1);
// socket creation
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// dserver address9002
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, MAX_CONNECTIONS);
int client_socket;
int i = 0;
while(client_counter < 2 && (client_socket = accept(server_socket, NULL,NULL)))
{
client_counter++;
client_sockets[i] = client_socket;
i++;
printf("new client ! \n");
}
//here i create a thread for each client and in this thread there is a while loop with a recv function
}
Client
int socket_connection(char* ip, int port)
{
int network_socket = 0;
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port);
server_address.sin_addr.s_addr = inet_addr(ip);
if ((network_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
int connection_status = connect(network_socket, (struct sockaddr*) &server_address, sizeof(server_address));
if (connection_status < 0)
{
printf("Error while creating / connecting the socket");
return -1;
}
return network_socket;
}
void connect_to_server()
{
char ip[256];
int port;
strcpy(ip, "127.0.0.1");
port = 9002;
// try to connect to the server with the IP and port
int network_socket = socket_connection(ip, port);
char server_reponse[256];
char message[256];
// clean string
memset(server_reponse, 0, sizeof(server_reponse));
recv(network_socket, &server_reponse, sizeof(server_reponse), 0);
if (strcmp(server_reponse, "instruction: make board") == 0)
{
construct_game_board();
show_game_board();
memset(message, 0, sizeof(message));
put_ship(message);
printf("Finish to make board\n");
}
printf("Reponse send to socket %d: %zu\n",network_socket, send(network_socket, message, strlen(message), 0));
while (1) {
printf("Before recv\n");
printf("Reponse recv : %zu\n", recv(network_socket, server_reponse, sizeof(server_reponse), 0));
printf("After recv\n");
}
In my console when i launch i have : Reponse send to socket 3: 0 and Before recv
I have a client requesting data (DA) from server A, and then I need to send DA to a second server B. I got it while the data is not larger than the buffer. However the following is not working for passing all data from A to B. I notice that when I create the socket_fwd and connect after closing the first sockfd, it works. But since I need to forward all data, I need to process all incomming as soon as it arrives
int sockfd, sockfd_fwd, n, n_fwd;
gint BUFFER=900;
char buf[BUFFER];
char* addr = "11.0.0.20"; //Server A listening on port 80
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
char chunk[BUFFER];
gint nfw;
gint total_recv = 0;
gint total_fwd = 0;
struct sockaddr_in server_addr2 = {0};
server_addr2.sin_port = htons(5555);
server_addr2.sin_family = AF_INET;
char *addr2 = "127.0.0.1"; //Server B listening on port 555
//#################Request data from A:80 ###########################
if(inet_pton(AF_INET, addr, &server_addr.sin_addr) != 1){
perror("inet_pton");
return -1;
}
sockfd = socket(AF_INET, (SOCK_STREAM), 0); //socket with server A
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Error on connect");
send(sockfd, buffer, strlen(buffer), 0); //Buffer contains something like get xx Kib to the server
bzero(buffer, BUFFER);
if(inet_pton(AF_INET, addr2, &server_addr2.sin_addr) != 1){
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Error inet pton");
return -1;
}
if(inet_pton(AF_INET, addr2, &server_addr2.sin_addr) != 1){
perror("inet_pton");
return -1;
}
sockfd_fwd = socket(AF_INET, (SOCK_STREAM), 0); //socket with server B
if (connect(sockfd_fwd, (struct sockaddr*)&server_addr2, sizeof(server_addr2)) < 0)
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Error on connect");
while ((n = recv(sockfd, chunk, BUFFER, 0)) > 0) {
total_recv += n;
mylog(G_LOG_LEVEL_MESSAGE, __FUNCTION__,"Recv chunk %s num-bytes:%i",chunk,total_recv);
nfw = send(sockfd_fwd, chunk ,n, 0);
memset(chunk,0,BUFFER);
}
close(sockfd);
close(sockfd_fwd);
This is a simple iterative client-server program. Where the server prints out "Received request" on successful establishment of connection.
server side
#define LENGTH 256
#define SERV_PORT 4000
#define LISTENQ 8
int main()
{
int listenfd, connfd, n;
socklen_t clilen;
char buf[LENGTH];
struct sockaddr_in cliaddr, servaddr;
//creation of socket
listenfd = socket (AF_INET, SOCK_STREAM, 0);
//creating socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
// printf("\nServer running.. waiting for connections");
// listen(listenfd, LISTENQ);
for(; ;)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
printf("\nReceived request");
//sleep(5);
}
return 0;
}
client side
#define LENGTH 256
#define SERV_PORT 4000
int main( int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
char buff[256];
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket failed");
exit(1);
}
server.sin_family = AF_INET;
hp = gethostbyname(argv[1]);
if(hp == 0)
{
perror("gethost by name failed");
exit(1);
}
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_port = htons(4000);
if(connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
{
perror("\nconnect failed");
exit(1);
}
return 0;
}
When I run this multiple client-server code, the output for first client is different from the preceding clients. I need the first client to output like others. Can someone help?
When the first client establishes a connection with the server, the server doesn't output "Received request", where as, for the other clients do output "Received request".
You need to restore the listen() call. – EJP
I have two server codes:
the first server: send the client a char each time until the string is finished
int
main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
char temp[1];
int i = 0;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999); /* daytime server */
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
connfd = Accept(listenfd, (SA *) NULL, NULL);
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
for(i = 0; i < strlen(buff); i++)
{
temp[0] = buff[i];
Write(connfd, temp, strlen(temp));
}
Close(connfd);
}
}
the second server: send the client a string
int
main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
char temp[1];
int i = 0;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999); /* daytime server */
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
connfd = Accept(listenfd, (SA *) NULL, NULL);
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}
the client:receive the chars sent by the server
int
main(int argc, char **argv)
{
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
int count = 0;
if (argc != 2)
err_quit("usage: a.out <IPaddress>");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9999); /* daytime server */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
count++;
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
printf("read time:%d\n", count);
exit(0);
}
the result is both of the output of variable count is 1. My question is why the first server's output is 1, I think the result should be strlen(buff) for the 1st server?
PS:I run the server and client on the same machine.
TCP is a stream protocol. As such the number of writes on one side will not cause the same amount of reads on the other side since the protocol doesn't preserve information about how the writes into the socket were made.
Usually, on the sender side there's a delay before a packet is sent in case you write more data to the socket so that more data can be stuffed into the same packet. One of the reasons for it is that a badly written server might flood the network with single byte packets.
On the receiver side, the protocol doesn't know why your data might have arrived as separate packets, it might have been split up because of the MTU, it might have been reassembled by some packet inspection software or appliance on the way, so whenever you read from your socket it will give you as much data as it can regardless of how it was sent to you.
On a local machine like in your setup it's likely that the client isn't even running while the server is writing, so even without buffering on the sender side it will not start reading until the server has written everything and therefore it will read everything in one go. Or not, you might be unlucky, your server gets preempted for long enough that the TCP implementation in your kernel thinks that there won't be any more data you'll be sending, send a single byte to the client, the client gets scheduled to run before the server runs again and the client will receive just one byte in the first read.
I'm trying to make a program (client) which kan send a message to a server upon request from user. Stripped down code follows:
Client:
int main(int argc, char **argv) {
struct sockaddr_in servaddr;
int sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6789);
servaddr.sin_addr.s_addr = inet_addr(<ip_address_of_server>);
while(1) {
char message[161];
fgets(message, 161, stdin);
/* Replacing '\n' with '\0' */
char *tmp = strchr(message, '\n');
if (tmp) *tmp = '\0';
connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
send(sock, message, strlen(message), 0);
close(sock);
}
}
Server:
int main(int argc, char **argv) {
struct sockaddr_in servaddr;
int sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6789);
bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(sock, 5);
while(1) {
int clisock = accept(sock, (struct sockaddr *) NULL, NULL);
if (clisock >= 0) {
int messageLength = 160;
char message[messageLength+1];
int in, index = 0, limit = messageLength;
while ((in = recv(clisock, &message[index], messageLength, 0)) > 0) {
index += in;
limit -= in;
}
printf("%s\n", message);
}
close(clisock);
}
}
Now, this works for the first message I send. But then it is not able to make another connection (I get the error message "Bad file descriptor" when trying to connect in the Client program.) Can anyone see what I have misunderstood? Thank you :)
your client programme also does the same mistake, first time you open the socket but after the first connection is done you close the socket, so the next time in the loop the socket descriptor is not valid, you need to re-open the socket but that's missing, please remove the socket call from top and add the below line in the start of while loop
int sock = socket(AF_INET, SOCK_STREAM, 0);
The problem is that you're closing the listening socket sock, instead of the client socket clisock.
servaddr.sin_addr.s_addr = inet_addr(<ip_address_of_server>);
instead of the above lines in your client code use the following
inet_pton(AF_INET,"<ipofserver>",&servaddr.sin_addr);
perform an error check for the fllowing function also.