Simple Socket Server And Client Use C Language
服务端(Linux版)
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX 80
#define PORT 2087
#define SA struct sockaddr
// Function designed for chat between client and server.
void func(int sockfd)
{
char buff[MAX];
for(;;)
{
bzero(buff, sizeof(buff));
recv(sockfd, buff, sizeof(buff), 0);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
printf("From Client : %s", buff);
send(sockfd, buff, sizeof(buff), 0);
}
}
static void sig_handler(int sig){
int retval;
if ( sig == SIGCHLD ){
// 等待子程序的結束狀態
wait(&retval);
printf("CATCH SIGNAL PID=%d\n",getpid());
}
}
// Driver function
int main(void)
{
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
socklen_t len;
pid_t pid;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
int reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int)) == -1)
printf("Can't set the reuse option on the socket");
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
else
printf("Server listening..\n");
while(1)
{
// Accept the data packet from client and verification
len = sizeof(cli);
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server acccept failed...\n");
exit(0);
}
else
printf("server acccept the client...\n");
// 呼叫 signal 來接收 SIGCHLD 信號
signal(SIGCHLD,sig_handler);
pid = fork();
if(pid < 0)
printf("ERROR on fork");
if(pid == 0)
{
close(sockfd);
// Function for chatting between client and server
func(connfd);
close(connfd);
exit(0);
}
else
{
close(connfd);
}
}
// After chatting close the socket
close(sockfd);
return 0;
}客户端(Windows版)
#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <ws2tcpip.h>
#define MAX 80
#define PORT 2087
#define SA struct sockaddr
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0)
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#pragma warning(disable:4996)
void func(int sockfd)
{
char buff[MAX];
int n;
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
;
send(sockfd, buff, sizeof(buff),0);
bzero(buff, sizeof(buff));
recv(sockfd, buff, sizeof(buff),0);
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}
}
int main(void)
{
WSADATA wsa;
int sockfd;
struct sockaddr_in servaddr;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
// socket create and varification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.1.234");
servaddr.sin_port = htons(PORT);
// connect the client socket to server socket
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
exit(0);
}
else
printf("connected to the server..\n");
// function for chat
func(sockfd);
// close the socket
closesocket(sockfd);
WSACleanup();
return 0;
}服务端使用fork()创建多进程,可同时处理多个客户端的通信,另外也使用SIGCHLD信号来处理僵尸子进程。
评论已关闭