TCP并发服务器的写法:
server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#define BUFFLEN 1024
#define SERVER_PORT 8888
#define BACKLOG 5
#define PIDNUMB 3
static void handle_connect(int s_s)
{
int s_c; /*客户端套接字文件描述符*/
struct sockaddr_in from; /*客户端地址*/
socklen_t len = sizeof(from);
/*主处理过程*/
while(1)
{
/*接收客户端连接*/
s_c = accept(s_s, (struct sockaddr*)&from, &len);
time_t now; /*时间*/
char buff[BUFFLEN]; /*收发数据缓冲区*/
int n = 0;
memset(buff, 0, BUFFLEN); /*清零*/
n = recv(s_c, buff, BUFFLEN,0); /*接收发送方数据*/
if(n > 0 && !strncmp(buff, "TIME", 4)) /*判断是否合法接收数据*/
{
memset(buff, 0, BUFFLEN); /*清零*/
now = time(NULL); /*当前时间*/
sprintf(buff, "%24s\r\n",ctime(&now)); /*将时间复制入缓冲区*/
send(s_c, buff, strlen(buff),0); /*发送数据*/
}
/*关闭客户端*/
close(s_c);
}
}
void sig_int(int num)
{
exit(1);
}
int main(int argc, char *argv[])
{
int s_s; /*服务器套接字文件描述符*/
struct sockaddr_in local; /*本地地址*/
signal(SIGINT,sig_int);
/*建立TCP套接字*/
s_s = socket(AF_INET, SOCK_STREAM, 0);
/*初始化地址和端口*/
memset(&local, 0, sizeof(local)); /*清零*/
local.sin_family = AF_INET; /*AF_INET协议族*/
local.sin_addr.s_addr = htonl(INADDR_ANY); /*任意本地地址*/
local.sin_port = htons(SERVER_PORT); /*服务器端口*/
/*将套接字文件描述符绑定到本地地址和端口*/
bind(s_s, (struct sockaddr*)&local, sizeof(local));
listen(s_s, BACKLOG); /*侦听*/
/*处理客户端连接*/
pid_t pid[PIDNUMB];
int i =0;
for(i=0;i<PIDNUMB;i++)
{
pid[i] = fork();
if(pid[i] == 0) /*子进程*/
{
handle_connect(s_s);
}
}
while(1);
close(s_s);
return 0;
}
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define BUFFLEN 1024
#define SERVER_PORT 8888
int main(int argc, char *argv[])
{
int s; /*服务器套接字文件描述符*/
struct sockaddr_in server; /*本地地址*/
char buff[BUFFLEN]; /*收发数据缓冲区*/
int n = 0; /*接收字符串长度*/
/*建立TCP套接字*/
s = socket(AF_INET, SOCK_STREAM, 0);
/*初始化地址*/
memset(&server, 0, sizeof(server)); /*清零*/
server.sin_family = AF_INET; /*AF_INET协议族*/
server.sin_addr.s_addr = htonl(INADDR_ANY);/*任意本地地址*/
server.sin_port = htons(SERVER_PORT); /*服务器端口*/
/*连接服务器*/
connect(s, (struct sockaddr*)&server,sizeof(server));
memset(buff, 0, BUFFLEN); /*清零*/
strcpy(buff, "TIME"); /*复制发送字符串*/
/*发送数据*/
send(s, buff, strlen(buff), 0);
memset(buff, 0, BUFFLEN); /*清零*/
/*接收数据*/
n = recv(s, buff, BUFFLEN, 0);
/*打印消息*/
if(n >0){
printf("TIME:%s",buff);
}
close(s);
return 0;
}
先运行server.c,然后在运行client.c,可以看到服务端每次客户端连接都返回当前的时间,并打印出来,然后关闭客户端。
客户端代码可以是多种方式:我自己写了中java的方式来连接:
public static void main(String args[]) {
Socket socket =null;
try {
socket = new Socket("119.29.85.118", 8888);
System.out.println("socket has connected");
//2.得到socket读写流
int i =0;
while(i<10){
OutputStream os=socket.getOutputStream();
OutputStreamWriter pw=new OutputStreamWriter (os);
BufferedWriter bw = new BufferedWriter(pw);
bw.write("TIME");
bw.flush();
// 从服务端程序接收数据
InputStream ips = socket.getInputStream();
InputStreamReader ipsr = new InputStreamReader(ips);
BufferedReader br = new BufferedReader(ipsr);
String s = "";
while((s = br.readLine()) != null)
System.out.println(s);
i++;
}
socket.close();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
同样,返回时间,本例子中,IP为服务端IP,是服务器的公网IP.