I wrote C code to control traffic lights between 2 raspberry Pi, and it works perfectly. However, I have a huge problem: I wrote all the code on my desktop computer and I wanted to change to my laptop. So I changed the IP address in my client, and now the TCP connection fails...
So I run my server.c first, and then my client.c, but after few seconds, I have the message "Connection failed". I really don't understand why, because it worked in my other computer with the same configuration. I give you only the code with the TCP connection.
Here is my code for the connection:
client.c:
/* TCP Variables*/
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0}; // message receive from RaspberryPI 1
void configurationTCP()
{
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "192.168.137.193", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
}
}
int main()
{
// Start Message
printf("test!!\n");
// Enter Start Button
scanf("hey");
configureGPIOs();
launchTests();
// COnfigure TCP connection :
configurationTCP();
}
server.c:
void configurationTCP()
{
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
}
Related
i am writing a program that 2 players wants to connect to the server to play rock, paper and scissors.The first player connects to the port 60000 and when the second player want to connect it tries to connect to port 60000. if it fails, it will connect to port 60001. At this moment i am not sure how to implement the second player.
Client:
int sock = 0;
char *hostname = "127.0.0.1";
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
// Clear this field; sin_zero is used for padding for the struct.
memset(&(serv_addr.sin_zero), 0, 8);
// Lookup host IP address.
struct hostent *hp = gethostbyname(hostname);
if (hp == NULL) {
fprintf(stderr, "unknown host %s\n", hostname);
exit(1);
}
serv_addr.sin_addr = *((struct in_addr *) hp->h_addr);
serv_addr.sin_port = htons(PORT);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
//getting the user name
printf("please enter your name:");
scanf("%s",buffer);
send(sock , buffer , strlen(buffer) , 0 );
//initializing the game
read( sock , buffer, 1024);
//playing the game until the user enters e
do{
printf("%s",buffer);
memset(buffer,0,sizeof(buffer));
scanf("%s",buffer);
while(check_input(buffer)==0){
printf("wrong input,try again:");
memset(buffer,0,sizeof(buffer));
scanf("%s",buffer);
}
send(sock , buffer , strlen(buffer) , 0 );//sending the input to the server
printf("client:sent %s\n",buffer);
read( sock , buffer, 1024);
printf("client:received %s\n",buffer);
}while(is_over(buffer)==2);
return 0;
in server:
char player1Name[1024];
char player2Name[1024];
int p1_score = 0;
int p2_score = 0;
char buffer[1024] = {0};
int server_fd;
int server_fd2;
int player1_socket;
int player2_socket;
struct sockaddr_in player1;
struct sockaddr_in player2;
int opt = 1;
int opt2=1;
int player1len = sizeof(player1);
int player2len = sizeof(player2);
// Creating socket file descriptor for player 1
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){
perror("socket failed");
exit(EXIT_FAILURE);
}
// Creating socket file descriptor for player 2
if ((server_fd2 = socket(AF_INET, SOCK_STREAM, 0)) == 0){
perror("socket failed");
exit(EXIT_FAILURE);
}
// making the first socket reusable
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt))){
perror("setsockopt");
exit(EXIT_FAILURE);
}
// making the second socket reusable
if (setsockopt(server_fd2, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt2, sizeof(opt2))){
perror("setsockopt");
exit(EXIT_FAILURE);
}
//specifying the address of the first player
player1.sin_family = AF_INET;
player1.sin_addr.s_addr = INADDR_ANY;
player1.sin_port = htons( PORT1 );
//specifying the address of the second player
player2.sin_family = AF_INET;
player2.sin_addr.s_addr = INADDR_ANY;
player2.sin_port = htons( PORT2 );
// Forcefully attaching socket to the port 6000
if (bind(server_fd, (struct sockaddr *)&player1, sizeof(player1))<0){
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 1) < 0){
perror("listen");
exit(EXIT_FAILURE);
}
if ((player1_socket = accept(server_fd, (struct sockaddr *)&player1,(socklen_t*)&player1len))<0){
perror("accept");
exit(EXIT_FAILURE);
}
get_playerName(player1Name,&player1_socket);
// Forcefully attaching socket to the port 6001
if (bind(server_fd2, (struct sockaddr *)&player2, sizeof(player2))<0){
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd2, 1) < 0){
perror("listen");
exit(EXIT_FAILURE);
}
if ((player2_socket = accept(server_fd2, (struct sockaddr *)&player2,(socklen_t*)&player2len))<0){
perror("accept");
exit(EXIT_FAILURE);
}
get_playerName(player2Name,&player2_socket);
char input1;
char input2;
do{
input1=get_nextMoves(player1Name,buffer,&player1_socket);
printf("%c\n",input1);
input2=get_nextMoves(player2Name,buffer,&player2_socket);
printf("%c\n",input2);
evaluate(input1,input2,&p1_score,&p2_score);
}while(input1!='e' && input2!='e');
strcpy(buffer,result(1,p1_score,p2_score));
send(player1_socket , buffer , strlen(buffer) , 0 );
strcpy(buffer,result(2,p1_score,p2_score));
send(player2_socket , buffer , strlen(buffer) , 0 );
return 0;
At this moment, i am running this code for both the player 1 and player 2 for the sake of experiment.When i run player 2 code, it just get stuck.
I was hoping for an error(EADDRINUSE more specifically).What is going on? how can i go further with my code?
In order for you to get an error, the server has to close the socket that's listening on port 6000 when the first client connects. Otherwise, your connection will succeed, but hang because the server doesn't call accept() a second time.
If the server does this, then the second client should get the error ECONNREFUSED, and it can try the second port.
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
if (errno == ECONNREFUSED) {
serv_addr.sin_port = htons(PORT + 1);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
} else {
printf("\nConnection Failed \n");
return -1;
}
}
Note, however, that this has a potential failure mode due to a timing window. If both clients try to connect at about the same time, the second client's connection request might arrive before the server has closed the listening socket, so the call to connect() will still succeed, even though the server never processes that connection.
The solution to that requires a more elaborate server design, where it accepts the second connection and returns a response saying that the port is already being used. Although if it could do this, you wouldn't need two ports in the first place.
I am fairly new to socket programming. I saw a tutorial and tried implementing the programs in my Linux machine. The codes are :
CLIENT :
int main() {
char buf[256] = "In client";
// create the socket
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
//setup an address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(9002);
int status = connect(sock, (struct sockaddr *) &server_address, sizeof(server_address));
if(status == -1)
{
printf("There Was an error!");
}
recv(sock, buf, sizeof(buf), 0);
printf("\n %s \n", buf);
close(sock);
return 0;
}
SERVER:
int main() {
char server_message[256] = "You have reached the server!";
// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, 5);
int client_socket;
client_socket = accept(server_socket, NULL, NULL);
// send the message
send(client_socket, server_message, sizeof(server_message), 0);
// close the socket
close(server_socket);
return 0;
}
The code is self-explanatory. When I run the server and then the client, for the first time, it works. But when I do it again, just after the previous one, the Client gives the message - There Was an error!, that means the connection is not happening.
Can anyone help why is this occurring?
Thanks in advance!
You should be checking for errors for all system calls in your server. I'm guessing that your bind is failing, because the port is "already in use". The reason for this is that the connection from the previous instance of the server lingers for a while in the operating system's connection table.
You want to use setsockopt with SO_REUSEADDR to avoid the bind failure. Specifically, add this prior to the bind call.
int reuse = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
perror("setsockopt(SO_REUSEADDR) failed");
(And do check errors. Makes debugging these kinds of things much easier if you know when something fails. Also, use perror or strerror(errno) in order to find out exactly why it failed -- not just that it failed.)
Check out my whole code here and see how it runs.
This is the server
int main(){
SOCKET s, newsocket;
struct sockaddr_in server, client;
int receiving;
char clientMessage[2000], *message;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socker error at %d", GetLastError());
}else{
puts("socket created");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8080);
if(bind(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("err at binding %d", GetLastError());
}else{
puts("binded.");
}
listen(s, 3);
puts("listening to connections...");
int c = sizeof(struct sockaddr_in);
while((newsocket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET){
puts("connection accepted");
//send
message="hello client";
send(newsocket, message, strlen(message), 0);
recv(newsocket, clientMessage, 50, 0);
puts(clientMessage);
}
puts("waiting for a machine");
if(newsocket == INVALID_SOCKET){
printf("newsocket invalid at %d", GetLastError());
}
getchar();
closesocket(s);
WSACleanup();
}
This is the client
int main(){
SOCKET s;
struct sockaddr_in server;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket error At %d", GetLastError());
}else{
puts("socket initialised");
}
server.sin_port = htons(8080);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("176.40.201.72");
printf("server values are defined.. \n");
printf("connecting..\n");
if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("connection error %d" , GetLastError());
}else{
puts("connected");
}
return 0;
}
I'm developing client-server software. On server's side I use this code:
int listener_socket = socket(AF_INET, SOCK_STREAM, 0);
if (listener_socket < 0)
{
perror("opening socket error");
return;
}
/* set option for reuseaddr */
int mtrue = 1;
if(setsockopt(listener_socket,SOL_SOCKET,SO_REUSEADDR,&mtrue,sizeof(int)) != 0)
{
perror("setsockopt error");
return;
}
struct sockaddr_in serv_addr, cli_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
bzero((char *) &cli_addr, sizeof(cli_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* bind socket */
if (bind(listener_socket,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
{
perror("binding error");
return;
}
/* start listening */
listen(listener_socket,connections_limit);
int newsockfd;
/* infinite cycle */
while(1){
newsockfd = accept(listener_socket,(struct sockaddr*) &cli_addr,&clilen);
...
}
So my code blocks in accept() method and waiting for the new connection. When client connects, accept method returns correct non-negative socket descriptor (i can communicate with client using this descriptor) but it doesn't fill cli_addr structure. It remains zeroes. Why it happens?
i forgot this line before accept:
clilen = sizeof(cli_addr);
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 created a server socket in C. This is the most basic stuff like what you would fine in a simple TCP server example. Server code is below. I also created a client socket that runs on the host machine. Code also below. However, for some reason the client is not able to connect to the server. The IP address I used is the same as the one under the entry eth0 from the "ip addr" command. The network adapter of the VM is a bridged connection.
The exact same code works when both client and server run on the same machine (the host).
Thank you!
Server code:
int sockfd;
int clientfd;
struct sockaddr_in self;
struct sockaddr_in client_addr;
int addrlen = sizeof (client_addr);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
return EXIT_FAILURE;
}
printf("Socket descriptor is: %d\n", sockfd);
memset(&self, 0, sizeof (self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*) &self, sizeof (self)) != 0) {
perror("socket--bind");
return EXIT_FAILURE;
}
if (listen(sockfd, 20) != 0) {
perror("socket--listen");
return EXIT_FAILURE;
}
clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
Client Code:
int sock;
struct sockaddr_in server;
//struct sockaddr_in client;
struct hostent *hp;
//char buf[BUFFER_SIZE];
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die(6, "Opening stream socket");
printf("Client socket file descriptor is: %d\n", sock);
memset(&server, (char) 0, sizeof (server));
server.sin_family = AF_INET;
hp = gethostbyname(host_name);
if (!hp) {
//sprintf(buf, "%s: unknown host\n", host_name);
die(8, "%s: unknown host\n", host_name);
}
memcpy(hp->h_addr, &server.sin_addr, hp->h_length);
server.sin_port = htons((u_short) SERVER_PORT);
/* Try to connect */
if ((connect(sock, (struct sockaddr *) &server, sizeof (server))) < 0)
die(7, "%s", "Failed to connect stream socket\n");