SCTP server cannot send message over channels to client - c

The server receives messages from the client, but when sending back to the client through 3 channels, the sctp_recvmsg function returns -1. Sometimes when I run it works, but it happens every other time. Guys help me figure it out!
The server takes up a free port and displays it for connecting to clients. After that it listens on the socket and waits for a connection from the client. When connected, a separate stream is created which is engaged in customer service. After receiving the message, the stream sends back the received message via three channels to the client.
Server
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
vector<thread> threadPool;
void multichatThread(int newsock, int flags)
{
char buffer[512];
printf("Новый клиент!\n");
struct sctp_sndrcvinfo sndrcvinfo; // информация о пересылке
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{ // принимаем сообщение от клиента
printf("Error sctp_recvmsg!\n");
return;
}
printf("%s\n", buffer);
int i;
for (i = 0; i < 3; i++)
{ // по всем 3-м потокам отправляем информацию
if (sctp_sendmsg(newsock, (void *)buffer, (size_t)strlen(buffer), NULL, 0, 0, 0, i, 0, 0) == -1)
{ // отправляем клиенту сообщение
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}
}
close(newsock); // закрываем связь с клиентом
}
void createServer()
{
struct sockaddr_in server, client;
int sock;
// создание сокета
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create socket!\n");
return;
}
// структура для сервера
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY); // локальный адрес
server.sin_port = htons(0); // порт сервера
// связка
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error bind!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
initmsg.sinit_num_ostreams = 3; // входные потоки
initmsg.sinit_max_instreams = 3; // выходные потоки
initmsg.sinit_max_attempts = 2; // максимальное количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
// объявляем очередь
if (listen(sock, 5) == -1)
{
printf("Error listen!\n");
return;
}
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
perror("getsockname");
else
{
printf("Сервер создан!\n");
printf("IP: %s\n", inet_ntoa(sin.sin_addr));
printf("Port: %d\n", ntohs(sin.sin_port));
}
int newsock;
int clnlen = sizeof(client), flags;
while (true)
{
if ((newsock = accept(sock, (struct sockaddr *)&client, (socklen_t *)&clnlen)) == -1)
{
printf("Error accept!\n");
return;
}
thread chatThread(multichatThread, newsock, flags);
chatThread.detach();
threadPool.push_back(move(chatThread));
}
close(sock); // закрываем сокет сервера
}
int main()
{
createServer();
return 0;
}
The client receives the port and connects to the server. Then it sends a message to the server and waits for a response from the server through three channels.
Client
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void connectServer(string ip, uint16_t port)
{
// настройка структуры для сервера
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
// создаем сокет
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
memset(&initmsg, 0, sizeof(initmsg));
initmsg.sinit_num_ostreams = 3; // выходные потоки
initmsg.sinit_max_instreams = 3; // входные потоки
initmsg.sinit_max_attempts = 2; // количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
printf("Данные о сокете!\n");
printf("IP: %s\n", inet_ntoa(server.sin_addr));
printf("Port: %d\n", ntohs(server.sin_port));
// соединяемся с сервером
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error connect!\n");
return;
}
// отправка и прием сообщения
char buf[512] = "Hello!";
if (sctp_sendmsg(sock, (void *)buf, (size_t)strlen(buf), NULL, 0, 0, 0, 1 /* номер потока */, 0, 0) == -1)
{
printf("Ошибка отправки пакета к серверу!\n");
return;
}
struct sctp_sndrcvinfo sndrcvinfo;
int i, flags;
char buff[512];
for (i = 0; i < 3; i++)
{ // по 3-м каналам принимаем сообщения
bzero((void *)&buff, sizeof(buff));
if (sctp_recvmsg(sock, (void *)buff, sizeof(buff), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
printf("Ошибка отправки пакета от сервера!\n");
return;
}
printf("Сервер: %s\n", buff);
}
close(sock);
}
int main()
{
string ip;
uint16_t port;
cout << "Введите IP:";
cin >> ip;
cout << "Введите PORT:";
cin >> port;
connectServer(ip, port);
return 0;
}

First, check the errno value on error - it may help.
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}

Related

Sending binary data between client and server

I am implementing a simple server-client inter-process communication by sending data in binary format from the client to the server. The program is simple: it sends an unsigned number from 1 to 5, once at a time, in binary format. The server reads in the these binary data and converts it back to an unsigned int. However, when I tried to read in on the server size, my binary data was changing. How can I make the reading protocol to read in the data in a format that I sent. I appreciate all helps that I can get! Thank you.
Here is my implementation of the server:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <limits.h>
#include <netdb.h>
#define BUFFER_SIZE 10
int main(int argc, char *argv[])
{
int serv_sock, ret, data_socket;
socklen_t client_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in client_addr;
// char buffer[BUFFER_SIZE];
uint32_t buffer = 0;
FILE *fp;
char hostname[HOST_NAME_MAX];
char ipaddr[INET_ADDRSTRLEN];
char port[6];
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
if (serv_sock == -1)
{
perror("socket");
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(35000);
ret = bind(serv_sock, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)); // bind socket to server address
if (ret == -1)
{
printf("bind error: %s\n", strerror(errno));
exit(1);
}
listen(serv_sock, 20);
// get hostname
gethostname(hostname, HOST_NAME_MAX);
// get ip address
getnameinfo((struct sockaddr *)&serv_addr, sizeof(serv_addr), ipaddr, INET_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
// get port number
printf("Server %s is running on %s : %s\n", hostname, ipaddr, port);
while (1)
{
data_socket = accept(serv_sock, (struct sockaddr *)&client_addr, &client_sock);
// print client host name and ip address
getnameinfo((struct sockaddr *)&client_addr, sizeof(client_addr), hostname, HOST_NAME_MAX, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
printf("Client %s is connected to %s : %s\n", hostname, ipaddr, port);
if (data_socket == -1)
{
printf("accept error: %s\n", strerror(errno));
exit(1);
}
while (1){
int n = read(data_socket, &buffer, sizeof(uint32_t));
if (n == -1)
{
printf("read error: %s\n", strerror(errno));
exit(1);
}
if (n == 0)
{
break;
}
uint32_t temp = ntohl(buffer);
printf("%d\n", temp);
}
close(data_socket);
// if (!strncmp(buffer, "418", sizeof(buffer)))
// {
// break;
// }
}
close(serv_sock);
return 0;
}
Client implimentation:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int ret, data_socket, i;
unsigned int num_arr[5] = {1, 2, 3, 4, 5};
char send_str[100];
data_socket = socket(AF_INET, SOCK_STREAM, 0);
if (data_socket == -1)
{
perror("socket");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(35000);
ret = connect(data_socket, (const struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
{
printf("connect error: %s\n", strerror(errno));
exit(1);
}
for (i = 0; i < 5; i++)
{
// sprintf(send_str, "%d\n", num_arr[i]);
// now send data as binary data
uint32_t num = htonl(num_arr[i]);
printf("%d\n", num);
printf("%d\n", ntohl(num));
write(data_socket, &num, sizeof(num));
write(data_socket, "\n", 1);
}
uint32_t delimiter = htonl(-1);
write(data_socket, &delimiter, sizeof(uint32_t));
if (argc == 2)
{
if (strncmp(argv[1], "quit", 4) == 0)
{
printf("User quits\n");
ret = write(data_socket, "418\n", 4);
}
else
{
printf("Wrong Argument\n");
}
}
close(data_socket);
return 0;
}

Can unix domain socket datagram server send and receive at same file?

Refer to the this. UDP INET server and client can send and receive at same side.
But now I want use unix domain socket. Here are my code:
client:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SERVER_PATH "tpf_unix_sock.server"
#define DATA "Hello from client\n"
int main(void)
{
int client_socket, rc;
struct sockaddr_un remote, peer_sock;
char buf[256];
memset(&remote, 0, sizeof(struct sockaddr_un));
/****************************************/
/* Create a UNIX domain datagram socket */
/****************************************/
client_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
if (client_socket == -1) {
// printf("SOCKET ERROR = %d\n", sock_errno());
exit(1);
}
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SERVER_PATH);
strcpy(buf, DATA);
printf("Sending data...\n");
rc = sendto(client_socket, buf, strlen(buf), MSG_CONFIRM, (struct sockaddr *) &remote, sizeof(remote));
if (rc == -1) {
close(client_socket);
exit(1);
}
else {
printf("Data sent!\n");
}
int n, len;
len = sizeof(remote);
n = recvfrom(client_socket, buf, sizeof(buf),
0, (struct sockaddr *)&remote,
&len);
buf[n] = '\0';
printf("Server : %s\n", buf);
rc = close(client_socket);
return 0;
}
server:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "tpf_unix_sock.server"
int main(void){
int server_sock, len, rc;
int bytes_rec = 0;
struct sockaddr_un server_sockaddr, peer_sock;
char buf[256];
memset(&server_sockaddr, 0, sizeof(struct sockaddr_un));
memset(buf, 0, 256);
server_sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (server_sock == -1){
exit(1);
}
server_sockaddr.sun_family = AF_UNIX;
strcpy(server_sockaddr.sun_path, SOCK_PATH);
len = sizeof(server_sockaddr);
unlink(SOCK_PATH);
rc = bind(server_sock, (struct sockaddr *) &server_sockaddr, len);
if (rc == -1){
// printf("BIND ERROR = %d", sock_errno());
close(server_sock);
exit(1);
}
printf("waiting to recvfrom...\n");
bytes_rec = recvfrom(server_sock, buf, 256, MSG_WAITALL, (struct sockaddr *)&peer_sock, &len);
if (bytes_rec == -1){
// printf("RECVFROM ERROR = %d", sock_errno());
close(server_sock);
exit(1);
}
else {
printf("DATA RECEIVED = %s\n", buf);
}
strcpy(buf, "DATA ckt\0");
printf("Sending data...\n");
sleep(1);
rc = sendto(server_sock, buf, strlen(buf), MSG_CONFIRM, (struct sockaddr *)&peer_sock, sizeof(peer_sock));
printf("Data sent!\n");
close(server_sock);
return 0;
}
And server side print:
waiting to recvfrom...
DATA RECEIVED = Hello from client
Sending data...
Data sent!
client side print:
Sending data...
Data sent!
Then it block at "recvfrom" function.
So is there any way to make it send and receive at same side?
Thanks!

synchronization in simple socket programming in C

I want to create a simple multithreaded chat application in C using api. For the beginning, i wrote a simple server communicating with client but there is a problem in the order messages sent.
example output:
in server
*new_sock socket number: 4
Server:hello client
Client:hello server
Server:how are you?
Client:
Server:
in client
Server:hello client
Client:hello server
Server:how are you?
Client:
//server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <pthread.h>
void* connection_handler(void* socket_descriptor)
{
int socket = *(int *)socket_descriptor;
int n;
char server_buffer[256];
memset(server_buffer, 0, sizeof(server_buffer));
printf("Server:");
gets(server_buffer);
send(socket, server_buffer, strlen(server_buffer), 0);
memset(server_buffer, 0, sizeof(server_buffer));
while ((n = recv(socket, server_buffer, 255, 0)) > 0)
{
server_buffer[n] = '\0';
printf("Client:%s\n", server_buffer);
memset(server_buffer, 0, sizeof(server_buffer));
printf("Server:");
gets(server_buffer);
send(socket, server_buffer, strlen(server_buffer), 0);
memset(server_buffer, 0, sizeof(server_buffer));
n = 0;
}
close(socket);
free(socket_descriptor);
return 0;
}
int main(int argc, char *argv[])
{
int server_sock, client_sock, portno, client_len, n;
int *new_sock;
struct sockaddr_in server_addr, client_addr;
if(argc < 2)
{
printf("ERROR: no port provided.\n");
exit(1);
}
server_sock = socket(AF_INET, SOCK_STREAM, 0);
if(server_sock < 0)
{
printf("ERROR: opening socket.");
exit(1);
}
portno = atoi(argv[1]);
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portno);
server_addr.sin_addr.s_addr = INADDR_ANY;
if( bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 )
{
printf("ERROR: binding socket.");
exit(1);
}
listen(server_sock, 5);
pthread_t handler_thread;
while( client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_len) )
{
new_sock = malloc(sizeof(int));
*new_sock = client_sock;
printf("*new_sock socket number: %d\n", *new_sock);
if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
{
printf("ERROR: creating thread\n");
exit(1);
}
}
pthread_join(handler_thread, NULL);
printf("server shut down.\n");
return 0;
}
//client code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
int main(int argc, char* argv[])
{
int sock_descriptor, portno, n;
struct sockaddr_in server_addr;
char buffer[256];
if (argc != 2)
{
printf("usage: %s port\n", argv[0]);
exit(1);
}
portno = atoi(argv[1]);
sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (sock_descriptor < 0)
{
printf("ERROR: creating socket!\n");
exit(1);
}
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(portno);
if (connect(sock_descriptor, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
printf("ERROR: connecting server!\n");
exit(1);
}
memset(buffer, 0, sizeof(buffer));
while((n = recv(sock_descriptor, buffer, 255, 0)) > 0)
{
buffer[n] = '\0';
printf("Server:%s\n", buffer);
memset(buffer, 0, sizeof(buffer));
printf("Client:");
gets(buffer);
send(sock_descriptor, buffer, sizeof(buffer), 0);
memset(buffer, 0, sizeof(buffer));
}
if (n <= 0)
{
printf("ERROR: reading from socket");
exit(1);
}
return 0;
}
Join the threads right after it has been created , accept is a blocking call (I assume you have not modified the default behavior) . Threads are complex to analyze however , the call to join wont even come since blocking accept call in while loop.
while(1)
{
//do something here
...
if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
{
printf("ERROR: creating thread\n");
exit(1);
}
pthread_join(handler_thread, NULL); //Use it right after creating thread
}

Error in recvfrom in C socket programming?

Sorry for my not perfet english
I have to implement reliable communication using UDP protocol; for start, i'm tring realize a simple program; a client send a message to server with NULL in buffer; the servers understands it as a request, then sends to client response, which is a number;
code client:
/*
* newClient.c
*
* Created on: 22 lug 2017
* Author: claudio
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SERV_PORT 5193
#define MAXLINE 1024
void err_exit(char* str)
{
perror(str);
exit(EXIT_FAILURE);
}
int request_to_server(int sockfd,int* x,struct sockaddr_in addr)
{
int n;
if(sendto(sockfd, NULL, 0, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
err_exit("sendto\n");
n = recvfrom(sockfd,(char*)x,sizeof(int),0,NULL,NULL);
if (n < 0) {
perror("errore in recvfrom");
exit(1);
}
if(n > 0) {
printf("client received: %d\n",*(int*)x);
}
return 1;
}
int main(int argc, char *argv[ ]) {
int sockfd;
struct sockaddr_in servaddr;
int x;
if (argc != 2) {
fprintf(stderr, "utilizzo: daytime_clientUDP <indirizzo IP server>\n");
exit(1);
}
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { /* crea il socket */
perror("errore in socket");
exit(1);
}
memset((void *)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
err_exit("error in inet_pton for %s");
}
if(request_to_server(sockfd,&x,servaddr))
printf("client received %d from server\n",x);
exit(EXIT_SUCCESS);
}
this is server code:
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define SERV_PORT 5193
#define MAXLINE 1024
void err_exit(char* str)
{
perror(str);
exit(EXIT_FAILURE);
}
int generate_casual()
{
int x = random()%1000 + 1; //number between 1 and 1000
return x;
}
void listen_request(int sockfd,char* buff,struct sockaddr_in* addr,socklen_t* len)
{
struct sockaddr_in servaddr = *addr;
socklen_t l = *len;
printf("listening request\n");
if ( (recvfrom(sockfd, buff, MAXLINE, 0, (struct sockaddr *)&servaddr, &l)) < 0){
printf("errno code: %d\n",errno);
err_exit("recvfrom\n");
}
*addr = servaddr;
*len = l;
return;
}
int main(int argc, char **argv)
{
(void) argc;
(void) argv;
int sockfd;
socklen_t len;
struct sockaddr_in addr;
char buff[MAXLINE];
srand(time(NULL));
memset((void *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERV_PORT); /* numero di porta del server */
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
err_exit("errore in socket");
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("errore in bind");
exit(1);
}
listen_request(sockfd,buff,&addr,&len);
int n_ack = generate_casual();
//char* p =(char*)&n_ack;
if (sendto(sockfd, (char*)&n_ack, sizeof(int), 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
err_exit("sendto");
}
printf("server: client is connected\n");
return 0;
}
when i run, sometimes client receives correctly number; but sometimes i have an error on recvfrom with msg "Invalid argument" ed errno code is 22;
why this?I have no idea in which case it runs and when it doesn't work, code is the same..

C, Socket, pthread: read doesn't work on a new thread

I'm making a client-server program in C using threads.
I've got this problem: on the server, on thread #1 (number_one), function "read" works fine. But when I create another thread #2 (number_two), on this one something goes wrong. Parameters are passed in the right way (I think).
-->thread number_one
...
char message[256];
int new_connection=accept(master_sock,NULL,NULL);
pthread_t temp
if(pthread_create(&temp , NULL , number_two , (void*) &new_connection))
{
perror("pthread_create failed");
exit(-2);
}
else
{
puts("number_two created");
if(read(new_connection, message, 256) > 0)
printf("Message from client is %s", message);
}
if(pthread_detach(temp))
{
perror("detach failed");
exit(-3);
}
...
---> thread number_two
void *number_two(void *sock_desc)
{
int sock = *(int*)sock_desc;
int read_size;
char client_message[2000];
read_size=read(sock, client_message, 256);
client_message[read_size]='\0';
return 0;
}
In "number_one", read waits an input from the client, and then it sets correctly the buffer "message".
In "number_two", read does not wait the client and does not set the buffer "client_message".
Thank you.
Please try my code? it works, I think it is the same with your code.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#define INVALID_SOCKET_FD (-1)
int create_tcp_server_socket(unsigned short port, bool bind_local, int backlog,
char *caller_name)
{
int socket_fd = INVALID_SOCKET_FD;
struct sockaddr_storage server_addr;
unsigned int yes = 1;
// just try ipv4
if (socket_fd < 0 && (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) >= 0) {
struct sockaddr_in *s4 = (struct sockaddr_in *)&server_addr;
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
memset(&server_addr, 0, sizeof(server_addr));
s4->sin_family = AF_INET;
s4->sin_port = htons(port);
if (bind_local)
s4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
else
s4->sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(socket_fd, (struct sockaddr *)&server_addr,
sizeof(server_addr)) < 0) {
close(socket_fd);
printf("Server: Failed to bind ipv4 server socket.\n");
return INVALID_SOCKET_FD;
}
}
else if (socket_fd < 0) {
printf("Server: Failed to create server socket.\n");
return INVALID_SOCKET_FD;
}
if (listen(socket_fd, backlog) < 0) {
close(socket_fd);
printf("Server: Failed to set listen.\n");
return INVALID_SOCKET_FD;
}
return socket_fd;
}
pthread_t temp;
void *number_two(void *sock)
{
char buf[1024];
int fd = *(int *)sock;
int nread = read(fd, buf, 1024);
write(STDOUT_FILENO, buf, nread);
return NULL;
}
int main()
{
pid_t pid;
if ((pid = fork()) < 0) {
}
else if (pid > 0) { // parent, server
char buf[1024];
int fd = create_tcp_server_socket(8787, false, 10, "zz");
int new_fd = accept(fd, NULL, 0);
pthread_create(&temp, NULL, number_two, (void *)&new_fd);
}
else { // child, client
uint32_t ip;
struct hostent *hp = gethostbyname("localhost");
memcpy(&ip, hp->h_addr_list[0], hp->h_length);
struct sockaddr_in server_addr;
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = ip;
server_addr.sin_port = htons(8787);
int fd = socket(AF_INET, SOCK_STREAM, 0);
connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
write(fd, "abcd", 4);
}
pause();
return 0;
}

Resources